记录一次mysql联合索引失效问题

今天发现一条sql语句特别慢,跑了1.9秒,大致语句如下

SELECT DISTINCT c.id FROM table_name c WHERE c.`status` != 1 AND c.total >= 2 AND c.start_time >= '2020-01-01 00:00:00' AND c.start_time < '2020-08-01 00:00:00' AND c.id IN (....此处省略几百个id )

因为sqlalchemy无法跨库查询,而几百个几千个id是由另一个库的表里查询出来的
这个表已经有很多单独索引和联合索引
使用 explain 发现,key字段里,这个查询只使用id这个单独索引,没有使用到另一个status,total,start_time的联合索引,但是possible_keys里显示,可能用到联合索引,所以就很奇怪,然后开始网上搜索,有的说!=,<>这种不走索引,我就把c.`status` != 1 改为了 c.`status` in (2,3,4,5),但是结果还是没走后面的索引,还是用了id的单独索引
【记录一次mysql联合索引失效问题】为什么呢
之前还天真的以为,查询的字段顺序要和联合索引的字段顺序一致,结果还是没有用
然后将status条件之后的所有判断条件都注释掉,只使用c.`status` = 2 试一下,发现还是不行,就只改成 c.`status` = 3,发现使用了status的单独索引
后来发现是因为c.`status` = 2 这个条件数据量太大,数据库觉得使用索引开销太大,使用了全表扫描,这也是为什么c.`status` = 2的时候没有使用索引的原因,所以创建联合索引的时候,需要把排除最多数据的条件字段放在最开始,以上面的sql为例,联合索引创建为 start_time, status, total 这样的顺序,因为时间条件最先判筛选掉最多的数据,然后我查看发现status筛选掉的数据比total
这样的联合索引创建以后,上面的sql语句不变,执行时间为0.14秒

    推荐阅读