2013-07-07 63 views
1

对于一个表(我们说'食物'),有一个列'type',其中有一个潜在值[1,2,3,4],用于指定该条目的类型(例如水果)。正如我预期选择喜欢分类字段是否需要索引? (MySQL或MongoDB)

SELECT name FROM food WHERE type = 3 ;  

会经常叫,我不知道会索引在这种情况下建议。由于该字段不知该指数将是有用的只有几个值可能。(同样,对于MongoDB的?)

+0

这取决于正在运行的其他查询以及文档的架构和磁盘上的文档大小以及此服务器是否具有ssds – Sammaye

回答

2

这样的字段上的索引可能不是在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索引这个查询效率更高。

所以,回答你的问题是要小心指数,尤其是大表。如果确实在分类列上有索引,请将其作为复合索引,这样只有使用索引才能满足查询,而不必返回数据页面。

+0

哦nvm意识到这是一个MySQL答案,主要将MongoDB误解为问题 – Sammaye

+0

@Sammaye。 。 。我认为你是对的。我更新了答案(希望)能够更好地表达我想说的话。 –

+0

是的,这是更好,它同样适用于MongoDB在这种情况下以及 – Sammaye

2

具有指数是不太可能有帮助,但你应该用你的查询和数据测试。如果列中有几个不同的值,查询将返回表的行的大部分,并且读取索引等同于全表扫描。实际上,全表扫描甚至可能比读取索引更快。

如果行的类型在其他的查询使用它可以帮助有型为多列索引的一部分。

相关问题