美文网首页
什么情况下索引会失效?

什么情况下索引会失效?

作者: hellokitty小丸子 | 来源:发表于2021-08-06 19:21 被阅读0次

前提条件:
sms表索引:

index_smsId:`smsId`
index_mobile_createdAt:`mobile`, `createdAt`
index_status:`status`

whiteList表无索引字段

一、like 以%开头:

explain select * from sms WHERE smsId LIKE '%1'; 不生效.png

如果只查询带索引字段的列,可以命中:

explain select smsId from sms WHERE smsId LIKE '%1'; 生效.png

二、or语句前后没有同时使用索引:

当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效:

explain select * from sms WHERE smsId = '1' or channel = 1; 不生效.png
explain select * from sms WHERE smsId = '1' or mobile='138xxxxxxxx'; 生效.png

三、组合索引,不是使用第一列索引,索引失效:

explain select * from sms WHERE createdAt > '2021-03-13 15:05:38'; 组合索引.png

四、对查询的列上有运算或者函数的:

explain SELECT * FROM sms where substr(smsId,-2)='12'; 函数.png
explain select smsId from sms WHERE status+1 = 3; 运算.png

五、数据类型出现隐式转化:

这其实是四的一种特殊情况,如varchar不加引号的话可能会自动转换为int型,使索引无效:

explain select * from sms WHERE mobile=138xxxxxxxx 类型转化.png
mysql有个类型转换规则就是将“字符转成数字”,所以以上sql就等价于这样:

explain select * from sms WHERE cast(mobile as signed)= 138xxxxxxxx

六、连接查询中,按照优化器顺序的第一张表不会走索引:

explain select * from sms a left join whiteList b on a.smsId = b.mobile

此时a表sms上的smsId是有索引的,b表mobile无索引 无效.png
//相当于执行以下循环
List<Map<String,Object>> resultA=select * from sms a
for(Map<String,Object> map: resultA){
       List<Map<String,Object>> resultB=select * from whiteList b where b.mobile=map.get("smsId")
}

现在将表的连接位置互换:

explain select * from whiteList b left join sms a on a.smsId = b.mobile; 有效.png
//相当于执行以下循环
List<Map<String,Object>> resultA=select * from whiteList b
for(Map<String,Object> map: resultA){
       List<Map<String,Object>> resultB=select * from sms a where a.smsId=map.get("mobile")
}

改为右连:
explain select * from sms a right join whiteList b on a.smsId = b.mobile;


有效.png
//相当于执行以下循环
List<Map<String,Object>> resultA=select * from whiteList b
for(Map<String,Object> map: resultA){
       List<Map<String,Object>> resultB=select * from sms a where a.smsId=map.get("mobile")
}

从上面连接查询来看左外连接a表没有用到索引,这就是因为由于是左外连接,所以优化器的执行顺序是a表、b表,也就是说首先全表扫描a表,再根据a表的smsId值查询b表的值,所以a表无法用到索引。

七、在索引字段上使用not,<>,!=

八、如果mysql估计使用全表扫描要比使用索引快,则不使用索引

参考:
https://www.jianshu.com/p/3ccca0444432
https://www.cnblogs.com/wdss/p/11186411.html

相关文章

  • 什么情况下索引会失效?

    前提条件:sms表索引: whiteList表无索引字段 一、like 以%开头: explain select ...

  • 模糊查询%在最前面,能否或者怎么使用索引

    前言 众所周知,在索引时,如果模糊查询的%置于最前面,索引会失效。但是在%前置时,什么情况下会使用到索引? 补充 ...

  • 数据库篇

    1、mysql索引在什么情况下回失效1、查询条件包括or可能导致索引失效2、查询时字段类型是字符串,where时参...

  • 索引失效7字真言

    模型数空运最快 模->模糊查询 like 如果以%开头,索引会失效。 型->如果数据类型错误了,索引会失效。 数-...

  • mysql 索引失效分析

    索引并不会时时发生,有时就算是where查询字段中添加了索引,索引也会失效,下面我们来讲讲五种索引失效的场景。 1...

  • MySQL索引

    MySQL索引 索引介绍 索引原理与分析 组合索引 索引失效分析 索引介绍 什么是索引索引:包括聚集索引、覆盖索引...

  • 63 MySQL实战性能优化-optimizer_trace

    1,mysql索引性能优化最佳实战 2, 使用索引查询如何避免回表查询 3,为什么查询有时候加了索引也会失效? 4...

  • 举例说明哪些情况下索引会失效?

    如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因) 注意:要想使用or,又想让索引...

  • mysql 高级调优

    索引失效

  • 索引失效的情况

    1、组合索引不遵循最左匹配原则 2、组合索引前面索引列使用范围查询(<,>,like),会导致后续的索引失效 3、...

网友评论

      本文标题:什么情况下索引会失效?

      本文链接:https://www.haomeiwen.com/subject/qqtjvltx.html