分组依据/排序的MySQL索引

时间:2011-09-19 18:09:36

标签: mysql indexing

请参阅下面的查询。我应该在表上创建什么索引,以便查询将使用索引并避免使用临时和filesort?我已经尝试了许多不同的索引组合并阅读advice here,但我似乎无法弄明白。我的解释是说Using Where(没有索引)或Using Where Using Temporary, Using Filesort

这是一个简化的查询。所有列都是整数。

SELECT c1, Sum(c2) 
FROM table 
WHERE c3 IS NOT NULL 
AND c4 = 2011 
AND c5 = 0 
AND c6 In (6,9,11)  
GROUP BY c1

3 个答案:

答案 0 :(得分:7)

这应该对你有所帮助。重写您的查询,如下所示:

SELECT c1, Sum(c2) 
FROM table 
WHERE c4 = 2011 
AND c5 = 0 
AND c6 In (6,9,11)
AND c3 IS NOT NULL   
GROUP BY c1

现在在列(c4,c5,c6)上创建一个复合索引,其列为IN THAT ORDER。索引中的列应与WHERE子句中的列的顺序相同。否则索引将无效。这个索引的选择性足够窄,临时表上的文件排序(对于group by)应该很快。

将c3移动到查询末尾的原因如下。作为一个例子,让我们假设c3可以取0到100之间的值(或者它可以是NULL)。如果运行“IS NOT NULL”查询,则Mysql需要遍历几乎所有B-Tree索引,除了对应于NULL的边。因此,MySQL决定全表扫描比遍历索引中的所有不同路径更容易。另一方面,您将看到如果您的查询是“IS NULL”并且您的索引是(c3,c4,c5,c6),那么Mysql将使用此索引。这是因为在这种情况下,Mysql只需要遍历与NULL值对应的索引树部分。

MySQL需要的索引类型在很大程度上取决于所讨论的查询。正如@louis建议的那样,在所有列上创建索引不是一个好主意!

答案 1 :(得分:0)

我认为问题在于“ORDER BY 2 DESC”一词。即使c2被索引,SUM(C2)也不是。

至于你应该拥有哪些索引,这取决于数据,所以我无法真正评论。

答案 2 :(得分:-1)

根据经验,我应该说:为“where”子句中的所有列构建索引(但这里不是c6)

至少,c4和c5。

“group by”子句将对结果进行排序。如果结果中有很多记录,那么索引c1也很有用。

c3仅被测试为“非空”。但索引也可以改进,这是有待测试的。

Hopz这很有用。