请参阅下面的查询。我应该在表上创建什么索引,以便查询将使用索引并避免使用临时和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
答案 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这很有用。