MySQL索引失效的情况

目录

对索引使用函数

对索引使用表达式计算

存在索引隐式类型转换

[使用 Like 以通配符开头](#使用 Like 以通配符开头)

联合索引要没有遵循最左前缀法则

[Where 子句中的 OR(索引可能不会完全失效)](#Where 子句中的 OR(索引可能不会完全失效))

最左前缀法则的具体演示

[1. 能命中索引的情况](#1. 能命中索引的情况)

[2. 不能命中索引的情况](#2. 不能命中索引的情况)


对索引使用函数

复制代码
select * from t_user where length(name)=6;

对索引使用表达式计算

复制代码
select * from t_user where id + 1 = 10;

存在索引隐式类型转换

复制代码
select * from t_user where phone = 1300000001;
-- MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较。
-- 因此相当于  select * from t_user where CAST(phone AS signed int) = 1300000001;

使用 Like 以通配符开头

**LIKE '%xxx'**或 **LIKE '%xxx%'**通常会导致索引失效(无法使用索引进行快速查找)。

为什么会失效

原因:B+树索引的工作原理

索引好比字典的拼音目录

复制代码
字典结构(按拼音排序):
a-an → 安、按、案...
ang → 昂、肮...
ao → 奥、澳、傲...
ba → 八、巴、拔...

1. 等值查询(高效)

复制代码
WHERE name LIKE '张%'
-- 相当于:找拼音以"zhang"开头的字
-- 直接定位到"zhang"区域,然后顺序扫描 ✅

2. 后缀匹配(失效)

复制代码
WHERE name LIKE '%三'
-- 相当于:找拼音以"san"结尾的字
-- 索引是"an、ang、ao、ba..."的顺序
-- "san"可能出现在任何位置,必须全表扫描 ❌

联合索引要没有遵循最左前缀法则

创建联合索引时,需要注意创建时的顺序,联合索引 (a, b, c) 和 (c, b, a) 在使用的时候会存在差别

比如,如果创建了一个 (a, b, c) 联合索引,如果查询条件是以下这几种,就可以匹配上联合索引

where a=1;

where a=1 and b=2 and c=3;

where b=2 and a=1;

where c=3 and b=2 and a=1;

where a=1 and c = 3;

值得注意的是,字段 a 在where字句的顺序是不重要的

但若查询条件是以下这几种,因为不符合最左匹配原则,所以就无法匹配上联合索引,联合索引就会失效:

where b=2; -- 由于缺少了a字段,索引失效

where c=3; -- 由于缺少了a和b字段,索引失效

where b=2 and c=3; -- 由于缺少了a字段,索引失效

总结一句话:使用联合索引当where条件中缺少了联合索引左侧的列时,索引就会失效

为什么有最左前缀法则

补一张图帮助理解,表示

之所以有最左前缀法则,是因为联合索引的索引树是这样排列的,当缺少了左侧列为查询条件时,右侧字段列无法根据索引树去查找数据,所以索引失效

Where 子句中的 OR(索引可能不会完全失效)

复制代码
select * from t_user where id = 1 or age = 18;

索引为什么可能不会完全失效

最左前缀法则的具体演示

1. 能命中索引的情况

以下查询都包含最左列a,因此能匹配联合索引(MySQL 会自动调整WHERE子句中字段的顺序,不影响匹配):

  • WHERE a=1:只查a,匹配索引最左列;
  • WHERE a=1 AND b=2 AND c=3:匹配a→b→c全部列;
  • WHERE b=2 AND a=1:MySQL 会调整为WHERE a=1 AND b=2,匹配a→b;
  • WHERE c=3 AND b=2 AND a=1:调整为WHERE a=1 AND b=2 AND c=3,匹配全部列;
  • WHERE a=1 AND c=3:匹配a列,c能部分利用索引(但b列缺失,c的排序基于a相同、b相同的前提,所以c的查询效率比全匹配低,但仍能用到a的索引)。

2. 不能命中索引的情况

以下查询缺少最左列a,导致联合索引失效(只能全表扫描或走其他索引):

  • WHERE b=2:没有a,无法利用(a,b,c)的有序性(b的排序基于a相同的前提,缺少a时,b的顺序是无序的);
  • WHERE c=3:缺少a和b,c的排序基于a和b相同的前提,单独查c时,c的顺序完全无序;
  • WHERE b=2 AND c=3:缺少a,b和c的组合在无a的情况下是无序的。
相关推荐
龙腾-虎跃6 小时前
Docker 一键启动服务合集:Redis、MySQL、Kafka、MinIO、Prometheus 等(网盘转存防失效)
redis·mysql·docker·kafka·prometheus·小龙虾·miniio
闲云野鹤在人间17 小时前
MySQL|从理论、安装、备份到主从复制、MHA高可用详解
linux·运维·数据库·mysql·云计算
要开心吖ZSH19 小时前
MySQL 慢 SQL 排查操作手册-个人笔记版
java·笔记·sql·mysql·慢查询
Gl�ria20 小时前
MySQL 单机版 vs 高可用版:宕机排查 + 故障处理
mysql·adb·架构
Titan202421 小时前
MySQL索引学习笔记
笔记·学习·mysql
ClouGence1 天前
数据库迁移工具 CloudCanal v6.5.0.0 发布:新增 TDSQL PostgreSQL 多条链路,支持 MongoDB 双向同步
数据库·mysql·mongodb
这个DBA有点耶1 天前
Change Buffer深入:二级索引写入的隐形加速器与它的代价
数据库·mysql·代码规范
for_ever_love__1 天前
MySQL 事务隔离级别讲透:MVCC、幻读与四个级别怎么选
java·数据库·mysql·事务·mvcc·不可重复读·幻读
这个DBA有点耶1 天前
关系数据库管理系统选型指南:四步决策框架与主流产品技术路线对比
数据库·sql·程序人生·mysql·database·dba
我不会起名字3221 天前
MVCC 快照读为什么读不到刚提交的数据:ReadView 的 4 条可见性规则
数据库·mysql·innodb·mvcc·事务隔离