MySQL索引失效原因以及SQL查询语句不走索引原因详解

2024年 2月 3日 68.8k 0

MySQL索引失效原因以及SQL查询语句不走索引原因详解

今天领导在查询报表时,发现特别慢,于是引发一系列关于sql优化的工作,下面这篇文章主要给大家介绍了关于MySQL索引失效原因以及SQL查询语句不走索引原因的相关资料,需要的朋友可以参考下

日常工作中索引失效原因很多,这个需要平时的日积月累,不断学习,才能更正确的发挥索引的作用,下面简单总结一些索引失效原因。

1. 隐式的类型转换,索引失效

1

select * from test where num=13911111111; # 失效,num字段是varchar类型,没有加引号

假设某手机号列创建时是num varchar(15)

如果上面的手机号没有加引号,查询的时候是字符串跟数字的比较,它们类型不匹配,MySQL 会做隐式的类型转换,把它们转换为浮点数再做比较。隐式的类型转换,索引会失效。

2. 查询条件包含 or,可能导致索引失效

1

select * from test where mul=1 or noidx=2; # 可能失效,当mul设为索引列而noidx不是索引列时

索引+or+无索引的列:会先走索引列,但无索引的列会进行全表扫描,所以还不如不走索引,直接都全表扫描完事。如果or前后都有索引,那么可能走索引,也可能不走索引。

如果它一开始就走全表扫描,直接一遍扫描就完事。Mysql 优化器出于效率与成本考虑,遇到 or 条件,让索引失效,看起来也合情合理。

用or连接的两个含null索引字段,不走索引。但是,单个索引含null字段,是走索引的。

注意:如果 or 条件的列都加了索引,索引可能会走也可能不走,平时大家使用的时候,还是要注意一下这个 or,学会用 explain 分析。遇到不走索引的时候,考虑拆开两条 SQL。

3. like 通配符可能导致索引失效

并不是用了 like 通配符,索引一定会失效,而是 like 查询是以 % 开头,才会导致索引失效。

4. 查询条件不满足联合索引的最左匹配原则

MySQl 建立联合索引时,会遵循最左前缀匹配的原则,即最左优先。如果你建立一个(a,b,c)的联合索引,相当于建立了 (a)、(a,b)、(a,b,c) 三个索引。

5. 在索引列login_time上使用 mysql 的内置函数

1

2

select * from user where DATE_ADD(login_time,INTERVAL 1 DAY) = '2022-11-08 00:00:00'; # 失效

select * from user where login_time = DATE_ADD('2022-11-08 00:00:00',INTERVAL 1 DAY); # 有效

6. 对索引列age进行列运算(如,+、-、*、/), 索引不生效

1

select * from user where age-1 = 39; # 失效

7. 索引字段age上使用(!= 或者 , not in),索引可能失效

1

select * from user where age != 18; # 有可能失效

其实这个也是跟 mySQL优化器有关,如果优化器觉得即使走了索引,还是需要扫描很多很多行的哈,它觉得不划算,不如直接不走索引。平时我们用!= 或者 ,not in 的时候,要留点心眼。

8. 索引字段上使用 is null, is not null,索引可能失效 (查询结果行数)

很多时候,是因为数据量问题,导致了 MySQL 优化器放弃走索引。同时,平时我们用 explain 分析 SQL 的时候,如果 type=range, 要注意一下哈,因为这个可能因为数据量问题,导致索引无效。

9. 左右join连接,关联的字段编码格式不一样

如user 表的 name 字段编码是 utf8mb4,而 user_job 表的 name 字段编码为 utf8。

10. 索引自身失效

虽然索引有自我维护的能力,但数据表内容修改和更新频繁的情况下,也有可能索引失效,此时需要删除索引,重新建立索引。

总结

关于索引失效原因有很多,以上也只是简单介绍了一下,具体失效原因,还得去自己分析,具体方法就是SQL的执行计划 EXPLAIN 关键字了。
Mysql提供了这个关键字让我们优化索引,使查询更快,分析优化器的表连接,使它采用最优的顺序。使用这个 explain 关键字可以查看查询语句是否走索引了以及走了哪个索引。

1

2

# 命令行执行以下语句即可查看查询语句是否走了索引,在查询语句最前面加上 explain 即可

mysql> explain select * from sampleInfo where agents = "XXX中心有限公司";

如下图的 key 即表示该语句使用了索引 agents 。如果下图 key 那里的为NULL或者 type 那里为ALL,则表示该语句没有走索引,需要进行优化了。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论