在mysql中解释“explain”查询的结果

时间:2010-08-27 06:49:26

标签: sql mysql performance

我正在使用mysql表的索引。

我的查询是这样的

 EXPLAIN SELECT * FROM `logs` WHERE userId =288 AND dateTime BETWEEN '2010-08-01' AND '2010-08-27' 

我已在此表日志的字段userId上建立索引, 解释查询的结果如下所示。

id  select_type     table     type  possible_keys   key     key_len     ref     rows    Extra
1      SIMPLE         logs     ref      userId      userId      4       const   49560   Using where

问题是“我的索引真的很有用吗?”......

提前致谢

@fastmultiplication

我认为在这个字段上建立索引可能会增加mysql的负载,因为会有很多带唯一的条目(userId和dateTime)。 我尝试在userId_dateTime上添加索引,结果是

id  select_type     table   type    possible_keys            key        key_len     ref     rows    Extra
1      SIMPLE        logs    ref     userId_dateTime    userId_dateTime     4       const   63455   Using where

3 个答案:

答案 0 :(得分:2)

您的查询正在使用索引,是的,它们很有用。您可能会发现以下文档页面非常有用:

EXPLAIN Output Format
How MySQL Uses Indexes
Multiple-Column Indexes

此外:

Multiple column index vs multiple indexes

MySQL通常会使用返回最小行数的索引。在您的第一个示例中,MySQL使用userId索引将行数缩小到49560.这意味着userId不包含唯一值(如果是,则不需要日期范围条件)。由于dateTime列上没有索引,因此必须扫描每一行以查找符合日期范围条件的索引。

在第二个示例中,您似乎在userIddateTime上创建了一个复合(多列)索引。在这种情况下,似乎MySQL无法使用BETWEEN子句的索引的后半部分 - 我不知道为什么。使用两个单独的索引而不是多列索引来尝试它可能是值得的。您可能还想尝试将BETWEEN替换为:

'2010-08-01' >= AND <= '2010-08-27'

这应该是相同的,但请参阅以下错误报告,这可能会影响您的MySQL版本:

Optimizer does not use index for BETWEEN in a JOIN condition

答案 1 :(得分:1)

从“行”字段看起来MySQL仍然估计它必须查看很多行。

您也应该尝试在dateTime字段中添加索引。

对于这个特定的查询,可能是两个字段的索引。

alter table logs add index user_datetime (userId,dateTime);

答案 2 :(得分:0)

应该查询返回多少行?查询的运行速度有多快?

它看起来像一个非常简单的查询,它正在使用正确的索引,所以如果由于某种原因它很慢,可能是因为它必须实际返回大量数据。如果您对所有行实际上并不感兴趣,可以使用LIMIT来减少。