1

对于一个表(比如说“食物”),有一列“类型”,其潜在值 [1,2,3,4] 指定了该条目的类型(例如水果)。正如我所期望的那样

SELECT name FROM food WHERE type = 3 ;    

最常被调用,我想知道在这种情况下是否会推荐一个索引。由于该字段只有几个可能的值,我想知道索引是否有用。(对于 MongoDB 也是如此?)

4

2 回答 2

3

这样一个字段的索引在 MySQL 中可能没有用。实际上,这样的索引可能会使大多数查询变得更糟。

在某些情况下,索引总是会更快。这是一个使用索引中的列的查询,例如:

select count(type)
from food
where type = 3;

这更快,因为读取索引应该比读取表更快,因为数据更小(假设您可以包含索引中的所有列)。

在其他情况下,MySQL 在可用时使用表的索引。

您要问的问题是关于索引的“选择性”。考虑您的查询:

SELECT name
FROM food
WHERE type = 3 ; 

如果所有行都有type = 3,那么无论如何您都必须读取所有匹配的记录(以获取 的值name)。如果每页有一条记录,那么索引可能会对您有所帮助,因为它减少了页面读取次数。更现实的情况是一个页面包含 100 条记录。那么,如果 25% 的记录具有相同的类型,那么一个典型的页面上就会有 25 条这样的记录。基本上,仍然需要阅读每一页。问题是页面是按顺序读取(“全表扫描”)还是通过索引读取的。

这两种读取表格的方式是有区别的。在全表扫描中,页面是按顺序读取的,一旦读取了一个页面,就不会再次访问它。在索引读取中,页面是随机读取的,一次一条记录,一个页面可以被读取多次。在极端情况下,页面不适合页面缓存,并且同一页面被刷新到磁盘并为页面上的每条记录一次又一次地读取。效率极低。

您可以通过在type, name.

因此,您的问题的答案是要小心索引,尤其是对于大型表。当您在分类列上有索引时,请将其设为复合索引,这样您的查询就可以仅使用索引来满足,而不必返回数据页。

于 2013-07-07T12:34:50.310 回答
2

拥有索引不太可能有帮助,但您应该使用查询和数据对其进行测试。如果列的不同值很少,查询将返回表中相当大的一部分行,读取索引相当于全表扫描。事实上,全表扫描甚至可能比读取索引更快。

如果在其他查询中使用了该行的类型,则将该类型作为多列索引的一部分可能会有所帮助。

于 2013-07-07T12:37:06.173 回答