0

我有一个查询返回以下说明:

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 作为结果。

4

1 回答 1

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 (顺便说一句,它们是相同的)。

于 2012-10-31T10:47:47.210 回答