MySQL索引失效的10中场景总结

1.不满足最左匹配原则

假设一张表存在一个索引idx_code_age_name,索引字段顺序如下:

  1. code
  2. age
  3. name

显然字段code位于最左侧

还原满足最左匹配的索引生效场景

  • explain select * from user
    where code=’101’;
  • explain select * from user
    where code=’101’ and age=21
  • explain select * from user
    where code=’101’ and age=21 and name=’周星驰’

    还原不满足最左匹配索引失效场景

  • explain select * from user
    where name=’101’;
  • explain select * from user
    where age=21
  • explain select * from user
    where age=21 and name=’周星驰’

2.使用了select *

还原索引失效场景

  • explain
    select * from user where name=’苏三’;(走了全表扫描)

    还原索引生效场景

  • explain
    select * from user where name=’苏三’;(走了全表扫描)

    原理:如果select语句中的查询列,都是索引列,那么这些列被称为覆盖索引。这种情况下,查询的相关字段都能走索引,索引查询效率相对来说更高一些。
    而使用select *查询所有列的数据,大概率会查询非索引列的数据,非索引列不会走索引,查询效率非常低。

3. 索引列上有计算

假设id是表user的索引字段,如果使用当前索引字段做计算时会导致索引失效

还原索引失效场景

  • explain select * from user where id+1=2;

4. 索引列用了函数

假设height是表user的索引字段,如果在当前索引字段上使用函数时会导致索引失效

还原索引失效场景

  • explain select * from user where SUBSTR(height,1,2)=17

5.字段类型不同

假设code字段时user表的索引字段,该字段为字符串类型,如果按int类型查询时会导致失效

还原索引失效场景

  • explain
    select * from user where code=101;

    还原索引生效场景

  • explain
    select * from user where code=”101”;

6.like左边包含%

模糊查询,在我们日常的工作中,使用频率还是比较高的,但如果like用的不好,就可能会出现性能问题,因为有时候它的索引会失效。

还原索引失效场景

  • explain select * from user
    where code like ‘%1%’

    还原索引生效场景

  • explain select * from user
    where code like ‘10%’

7.列对比

假如我们现在有这样一个需求:过滤出表中某两列值相同的记录。比如user表中id字段和height字段,查询出这两个字段中值相同的记录。

还原索引失效场景

  • explain select * from user
    where id=height

8.使用or关键字

还原索引失效场景

  • explain select * from user
    where id=1 or height=’175’

9. not in和not exists

当使用in 或者 exists时索引会生效,反之则失效

还原索引失效场景

  • explain select * from user
    where height not in (173,174,175,176)

10. order by的坑

还原索引失效场景

  • 没加where或limit

    • explain select * from user
      order by code, name;
  • 对不同的索引做order by

    • explain select * from user
      order by code, height limit 100;
  • 不满足最左匹配原则

    • explain select * from user
      order by name limit 100;
  • 不同的排序

    • explain select * from user
      order by code asc,age desc limit 100;