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:缺少abc的排序基于ab相同的前提,单独查c时,c的顺序完全无序;
  • WHERE b=2 AND c=3:缺少abc的组合在无a的情况下是无序的。
相关推荐
流㶡1 小时前
mysql学习笔记之创建表、导入导出数据
数据库·mysql
shejizuopin2 小时前
基于SSM的高校旧书交易系统的设计与实现(任务书)
java·mysql·毕业设计·论文·任务书·基于ssm的·高校旧书交易系统的设计与实现
Wiktok3 小时前
SQLAlchemy+PyMySQL的实用实战示例
python·mysql·sqlalchemy
不想写bug呀3 小时前
MySQL事务介绍
数据库·mysql
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.3 小时前
双主模式实现HTTP与MySQL高可用
网络协议·mysql·http
cheems95273 小时前
【MySQL】SQL调优:数据库性能优化(一)
数据库·sql·mysql
qq_297574674 小时前
MySQL迁移到瀚高数据库 常用转换函数对照表(附XML示例,直接复用)
xml·数据库·mysql
Mr_Xuhhh4 小时前
MySQL复合查询详解:多表查询、子查询与合并查询
数据库·sql·mysql
Big Cole4 小时前
PHP 面试:MySQL 核心问题之索引与优化
mysql·面试·php
予枫的编程笔记5 小时前
【MySQL修炼篇】从S锁/X锁到Next-Key Lock:MySQL锁机制硬核拆解
mysql·锁机制·行锁·间隙锁·数据库运维·数据库性能优化·死锁排查