我有一个返回以下解释的查询:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE this_ index_merge CategoryId,Deleted,PublishedOn,_ComputedDeletedValue,_Temporary_Flag,Published,_TestItemSessionGuid Deleted,_ComputedDeletedValue,_Temporary_Flag,Published 1,1,1,1 6203 Using intersect(Deleted,_ComputedDeletedValue,_Temporary_Flag,Published); Using where
这是否表明查询在任何地方使用索引,还是可以通过添加其他索引来改进?基于此:http://dev.mysql.com/doc/refman/5.1/en/explain-output.html,它提到key
列显示实际使用的索引。每列都有一个索引。
有问题的查询如下:
SELECT SQL_NO_CACHE count(*) FROM
article this_
WHERE
(this_._Temporary_Flag = 0 OR this_._Temporary_Flag = NULL) AND
this_.Published = 1 AND
(this_.PublishedOn IS NULL OR this_.PublishedOn <= '2012-10-30 18:46:18 ') AND
(this_.Deleted = 0 OR this_.Deleted = NULL) AND
(this_._ComputedDeletedValue = 0 OR this_._ComputedDeletedValue = NULL) AND
((this_._TestItemSessionGuid IS NULL OR this_._TestItemSessionGuid = ''))
AND NOT (this_.CategoryId IS NULL)
表有大约140,000条记录。此查询执行时间为3秒,结果返回135,725。
答案 0 :(得分:1)
该解释显示,MySQL使用的索引是从4个单独的索引合并,密钥长度为1,1,1,1,这意味着所有四列都用于遍历搜索树。
但是,在所有列上使用单独的索引通常不是最有效的方法。特别是在你的情况下合并四个索引可能会花费很多时间。实际执行可能会更快,但构建索引可能需要1-2秒。
我建议在这些列上构建一个复合索引。这些事情的顺序。获得具有相同条件的条件并将它们按基数顺序排列(更大的基数优先)。最后一列是范围查询(在您的情况下是PublishedOn)。
例如:
create index my_query_IDX on article (Deleted, _Temporary_Flag, _ComputedDeletedValue, PublishedOn)
我建议的另一件事是将_Temporary_Flag,Deleted,_ComputedDeletedValue,_ Published等列更改为NOT NULL DEFAULT'0'。可空列和空值的索引效果不如非空列有效,正如我根据key_length看到的那样,这些列是BOOLEANS或TINYINT(顺便说一下,这些列相同)。