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的情况下是无序的。
相关推荐
@游子2 小时前
第二章-MySQL之手工注入(二)
数据库·mysql
前进的李工2 小时前
SQL入门:从零掌握数据库查询语言
数据库·sql·mysql
6***94152 小时前
MySQL 字符串日期格式转换
android·数据库·mysql
p***q782 小时前
MySQL——用户管理
android·mysql·adb
g***86692 小时前
MySQL - Navicat自动备份MySQL数据
android·数据库·mysql
q***01772 小时前
【MySQL】数据类型
android·数据库·mysql
o***59273 小时前
【MySQL系列文章】Linux环境下安装部署MySQL
linux·mysql·adb
O***P5713 小时前
【Mysql】:如何配置最大连接数?
数据库·mysql
p***32353 小时前
Linux系统离线部署MySQL详细教程(带每步骤图文教程)
linux·mysql·adb