MySQL中索引失效原理深入解析(保证给你讲的明明白白)

 更新时间:2026年08月08日 14:14:57   作者:叼个梨  
MySQL索引失效主要源于函数操作、类型转换、最左前缀缺失等场景,优化器选择受统计信息准确性、索引基数和预估扫描行数影响,这篇文章主要介绍了MySQL中索引失效原理的相关资料,需要的朋友可以参考下

MySQL索引失效的原因可以分为五个方面来讨论:

--违反最左前缀法则

--范围查询导致后续列失效

--在索引列上进行函数运算操作

--字符串不加单引号的情况

--以%开头的like模糊查询

一、首先,违反最左前缀法则:

当然前提是在查询时使用了联合索引的情况下

关于为什么违反最左前缀法则,我们应该回到MySQL中InnoDB引擎所使用的索引存储结构来刨析 

InnoDB 引擎使用 B+树 作为索引结构,而违反最左前缀法则导致索引失效的核心本质就是:B+树索引的有序性依赖

若在age,city,name三列上创建联合索引,其在b+树的叶子结点中的存储就会是:
(假设有这些数据)


而根节点存储的就是最左边age的范围,以通过age进行索引遍历到对应的叶子结点

b+树索引遍历的关键特性

  • 全局有序:整个索引按  age  第一优先级排序
  • 局部有序:在  age  相同的情况下,按  city  排序
  • 再局部有序:在  age  和  city  都相同的情况下,按  name  排序

若where 指定多个条件时,最左面的条件是age=20,就会根据根节点中的age进行遍历,

找到age,再根据叶子结点上的city进行查找,最后根据name进行查找

若where最左面的条件指定的是city=“北京”,由于根节点只存储最左边age的范围,而city的值只存储在最后的叶子结点上,无法根据city快速定位对应的叶子结点上,此时只能进行全表扫描挨个行匹配,造成索引失效

二、范围查询导致后续列失效

同样是b+树存储结构原因

参照之前提到过的b+树索引遍历的关键特性:

  • 全局有序:整个索引按  age  第一优先级排序
  • 局部有序:在  age  相同的情况下,按  city  排序
  • 再局部有序:在  age  和  city  都相同的情况下,按  name  排序

若where age > 20 and city = '北京'
使用  age > 20  定位到叶子结点,这可以走索引
问题在于  age > 20  的范围内, city  是无序的

如图:

在age都等于21时,其city再按照字符的ASCII码进行排序,“北京”<“广州”,排序好了两条

在age都等于22时,也完成了排序,排序出了一条

此时这两项拼接加一起时却是如上图所示的结构。

city不是按照字符顺序连续存储,city没有顺序就不能对city进行连续的扫描,只能在  age > 20  的结果集中,逐行过滤  city='北京' ,city列的索引失效

三、在索引列上进行函数运算操作

假设我们在  create_time  列上创建了索引,其该列的值有:

若进行where  YEAR(create_time) = 2023 时,是匹配不到的

索引存储的是"原始值"而非"计算结果",只存储原始时间字符串(如’2023-01-15 10:30:00‘),不存储  YEAR(create_time)  的计算结果2023,因此函数运算破坏了"导航能力",导致索引失效,只能逐行读取每条数据,计算  YEAR(create_time) ,再比较。

四、字符串不加单引号的情况

这是开发中最常见、最隐蔽的索引失效陷阱

=右面没有加单引号

select * from users where phone = 13800138000;

底层机制:MySQL 的隐式类型转换规则

当字符串列与数字比较时,MySQL 总是将字符串转换为数字,而不是反过来,原版phone是字符类型,但却被转换为数值类型。

而索引中存储的是字符类型的phone,无法与数值类型的phone匹配,导致索引失效

五、以%开头的like模糊查询

假设  name  列的索引  idx_name  存储以下数据:

  • name: '张三', '张三丰', '李四', '李小四', '王五'

比较规则是从第一个字符进行比较,之后是第二个字符比较以此类推

  • 若where name like ’张三%‘

就会从根节点匹配第一个字符‘张’,找到对应的子结点。

  • 若where name like ’%三‘

此时字符串以前缀模糊匹配,根本不知道第一个字符是什么,无法从根结点快速定位到叶子结点上,只能全表扫描,索引失效

因此这就是为什么使用like进行模糊查询时,只有前缀模糊索引会失效。

以上就是造成索引失效的具体原因,相信经过上述的分析,之后在索引的使用中可以做到避免索引失效的情况,也理解该如何使用索引,并对其进行优化。

到此这篇关于MySQL中索引失效原理深入解析的文章就介绍到这了,更多相关MySQL索引失效原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql 表空间及索引的查看方法

    mysql 表空间及索引的查看方法

    mysql 表空间及索引的查看方法,需要的朋友可以参考下。
    2011-07-07
  • MySQL性能指标TPS+QPS+IOPS压测

    MySQL性能指标TPS+QPS+IOPS压测

    这篇文章主要介绍了MySQL性能指标TPS+QPS+IOPS压测,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-08-08
  • MySQL 数据丢失排查案例

    MySQL 数据丢失排查案例

    这篇文章主要分享了MySQL 数据丢失排查的一个案例,帮助大家更好的理解和学习使用MySQL数据库,感兴趣的朋友可以了解下
    2021-05-05
  • 远程连接mysql数据库注意事项记录(远程连接慢skip-name-resolve)

    远程连接mysql数据库注意事项记录(远程连接慢skip-name-resolve)

    有时候我们需要远程连接mysql数据库,就需要注意下面的问题,方便大家解决,脚本之家小编特为大家准备了一些资料
    2012-07-07
  • mysql表优化、分析、检查和修复的方法详解

    mysql表优化、分析、检查和修复的方法详解

    这篇文章主要介绍了mysql表优化、分析、检查和修复的方法,结合实例形式较为详细的分析了MySQL表进行优化,分析与修复等操作的各种常见命令与使用技巧,需要的朋友可以参考下
    2016-04-04
  • Mysql存储过程中游标的用法实例

    Mysql存储过程中游标的用法实例

    这篇文章主要介绍了Mysql存储过程中游标的用法,以商户关联数据的插入及更新为例分析了MySQL存储过程中游标的使用技巧,需要的朋友可以参考下
    2015-07-07
  • MySQL中的套接字错误解决

    MySQL中的套接字错误解决

    socket文件是一种特殊的文件,可以促进不同进程之间的通信,有时候系统或MySQL配置的更改可能导致MySQL无法读取套接字文件,本文主要介绍了MySQL中的套接字错误解决,感兴趣的可以了解一下
    2024-02-02
  • mysql中各种常见join连表查询实例总结

    mysql中各种常见join连表查询实例总结

    这篇文章主要介绍了mysql中各种常见join连表查询,结合实例形式总结分析了MySQL中join连表查询的各种常见用法及相关操作注意事项,需要的朋友可以参考下
    2020-02-02
  • MYSQL中varchar和TEXT的相关问题详析

    MYSQL中varchar和TEXT的相关问题详析

    varchar 和 text 是 MySQL 字符存储争议比较多的领域,下面这篇文章主要给大家介绍了关于MYSQL中varchar和TEXT,文中介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • centos下安装mysql服务器的方法

    centos下安装mysql服务器的方法

    本篇文章是对在centos下安装mysql服务器的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06

最新评论