Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么MySQL不使用索引?_Mysql_Sql_Database - Fatal编程技术网

为什么MySQL不使用索引?

为什么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

我们的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 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
子句的优化器将多个可能的索引情况添加到
订单中,并且强制索引的一个非常小的情况实际上是合法的

还请注意,(…)
中的子句
对优化器来说是一个额外的麻烦


如果您真的不需要它,我建议按id
ASC
而不是
DESC
订购,这样引擎就可以利用主键订购的好处,即
ASC
,直到进一步实施。

您在[Seller]上的非群集索引可能有太多碎片,并且您的统计数据可能已经过时,那么查询优化器可能不会选择最佳查询计划。检查碎片,更新统计信息,或者在Seller上重新构建非集群索引,当然,如果您还可以为这个查询创建覆盖索引,如果这个查询经常被用户使用,并且值得为此付出代价的话。创建覆盖索引时,请确保顺序是最终用户通常使用的顺序。与您的查询一样,覆盖索引应该位于[seller->col1->col3->col4]

您应该对查询运行解释并发布结果。您需要向我们显示表和索引定义。诊断慢速查询需要完整的表和索引定义,而不仅仅是描述或解释。也许您的表定义不好。可能索引没有正确创建。也许你在你认为你有的专栏上没有索引。如果看不到表和索引定义,我们无法判断。如果您知道如何进行
解释
或获得执行计划,请将结果也放在问题中。谢谢,我的问题中有解释结果。