为什么MySQL不使用索引?
我们的MySQL(Percona服务器)数据库有一个包含1000万行的大表,有许多慢查询超过40秒,如下所示:为什么MySQL不使用索引?,mysql,sql,database,Mysql,Sql,Database,我们的MySQL(Percona服务器)数据库有一个包含1000万行的大表,有许多慢查询超过40秒,如下所示: 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
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
和col1
,col3
,col4
上创建了索引。这些索引是单独的,而不是多列索引(又称覆盖索引)。而Id
是主键
解释说明:MySQL使用主键作为索引来查询这个sql,而不是关于卖家的索引
+----+-------------+------------------+-------+--------------------+---------+---------+------+------+-------------+
| 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 |
+----+-------------+------------------+-------+--------------------+---------+---------+------+------+-------------+
当我力指数(卖方)
时,速度非常快,0.7秒
我发现如果不使用限制语句,这个查询将使用Seller
索引,速度会非常快。
为什么MySQL不在卖家上使用带有limit语句的索引?正如您所遇到的,拥有索引并不意味着它将被使用。这适用于每个数据库——索引选择取决于查询优化器。正如您所尝试的,强制索引并不意味着您将获得最快的结果 接下来,查询缓存可能对您没有帮助——可以缓存查询计划,因此甚至不考虑索引
MySQL每个语句只使用一个索引,所以覆盖索引(多列)是一个好主意,但您必须对其进行测试才能确定 通过DESC+
LIMIT
子句的优化器将多个可能的索引情况添加到订单中,并且强制索引的一个非常小的情况实际上是合法的
还请注意,(…)
中的子句对优化器来说是一个额外的麻烦
如果您真的不需要它,我建议按idASC
而不是DESC
订购,这样引擎就可以利用主键订购的好处,即ASC
,直到进一步实施。您在[Seller]上的非群集索引可能有太多碎片,并且您的统计数据可能已经过时,那么查询优化器可能不会选择最佳查询计划。检查碎片,更新统计信息,或者在Seller上重新构建非集群索引,当然,如果您还可以为这个查询创建覆盖索引,如果这个查询经常被用户使用,并且值得为此付出代价的话。创建覆盖索引时,请确保顺序是最终用户通常使用的顺序。与您的查询一样,覆盖索引应该位于[seller->col1->col3->col4]您应该对查询运行解释并发布结果。您需要向我们显示表和索引定义。诊断慢速查询需要完整的表和索引定义,而不仅仅是描述或解释。也许您的表定义不好。可能索引没有正确创建。也许你在你认为你有的专栏上没有索引。如果看不到表和索引定义,我们无法判断。如果您知道如何进行解释或获得执行计划,请将结果也放在问题中。谢谢,我的问题中有解释结果。