2013-03-18 89 views
2

我们的MySQL(的Percona Server)的数据库中有一个大桌子cotains 1000万行,有很多慢速查询longger超过40秒这样的:为什么MySQL不使用索引?

SELECT col1, Seller, col3, col4, Id, col5 
    FROM table1 
    WHERE Seller = 346761 
    AND col1 IN (2, 3, 4) 
    AND col3 = 1 
    AND col4 NOT IN (5,6,7) 
ORDER BY Id DESC 
    LIMIT 0, 20; 

我对Seller创建索引,col1col3col4 。这些指标是单独的,而不是多列指数(AKA覆盖指数)。 Id是主键。

EXPLAIN显示MySQL使用主键作为索引来查询这个sql,而不是关于Seller的索引。

+----+-------------+------------------+-------+--------------------+---------+---------+------+------+-------------+ 
| id | select_type | table   | type | possible_keys  | key  | key_len | ref | rows | Extra  | 
+----+-------------+------------------+-------+--------------------+---------+---------+------+------+-------------+ 
| 1 | SIMPLE  | trans_audit_list | index | Seller,AuditStatus | PRIMARY | 8  | NULL | 1483 | Using where | 
+----+-------------+------------------+-------+--------------------+---------+---------+------+------+-------------+ 

当我force index (Seller),它是非常快,0.7秒。

而我发现如果不使用限制语句,这个查询将使用Seller索引,会非常快。 为什么MySQL不使用带限制语句的Seller上的索引?

+0

您应该在查询上运行EXPLAIN并发布结果。 – 2013-03-18 03:09:37

+2

**您需要向我们展示表和索引定义。**诊断慢查询需要全表和索引定义,而不仅仅是描述或释义。也许你的表格定义不好。也许索引没有正确创建。也许你没有一个你认为你做过的那个专栏的索引。没有看到表和索引定义,我们不能说。如果你知道如何做一个'EXPLAIN'或者得到一个执行计划,那就把结果也放在问题中。 – 2013-03-18 03:13:23

+0

谢谢,我有我的问题发布EXPLAIN结果。 – KeepZero 2013-03-18 03:20:06

回答

1

将多个可能的索引情况添加到ORDER BY DESC + LIMIT条款is a common problematic situation for mysql的优化程序以及强制索引时非常小的情况之一实际上可能是合法的。

请注意,您的子句IN (...)是优化程序的额外麻烦。

如果你不是真的需要它,我建议按ID ASC而不是DESC来订购,这样引擎可以使用主键排序的好处,这是ASC,直到进一步实施。

1

正如你所遇到的,有一个索引并不意味着它会被使用。这适用于每个数据库 - 索引选择取决于查询优化器。正如你试过的,强制索引并不意味着你会得到最快的结果。

之后,查询缓存可能没有帮助你 - 查询计划可能被缓存,因此甚至不考虑索引。

MySQL只对每个语句使用一个索引,因此覆盖索引(多列)将是一个好主意,但您必须对其进行测试才能确定。

1

您的[Seller]上的非群集索引可能具有太多碎片,并且您的统计信息可能已过时,那么查询优化程序可能不会选择最佳查询计划。检查碎片,更新统计信息或在Seller上重新构建非集群索引,当然,如果您也可以为此查询创建覆盖索引,如果此查询经常由用户使用,并且它值得花费。当您创建覆盖索引时,请确保订单是最终用户最常使用的。与您的查询一样,覆盖索引应该位于[seller-> col1-> col3-> col4]