1015 字
约 3 分钟
7
S11-J02 · 索引失效的六种情况
2024-12-31
2026-11-07

适用读者:明明加了索引却还是慢的人。
前置:S11-B05、S11-J01。
实测环境:MySQL 8.0.46(s11lab,20,000 行,2026-11-05)。
覆盖旧文:1233(51) 853(98) 850(105) 1542(100) = 354 点。
覆盖扩展:E-S11-015(隐式转换的方向)、E-S11-016(OR 与索引合并)。
上一篇:S11-J01 · 回表与覆盖索引
下一篇:S11-J03 · Explain 逐列读。


1. 一句话结论

索引失效的本质是"优化器无法用索引的有序性快速定位"——函数包裹、前导模糊、类型转换、OR 混用、联合索引跳列、选择性太低。


2. 实测对照表(同一张表,同一批数据)

# SQL type key rows 结论
1 where age=30 ref idx_age 250 ✅ 正常
2 where age+1=31 ALL NULL 20000 ❌ 函数包裹
3 where age='30' ref idx_age 250 ✅ 字符串常量会被转成数字
4 where name like 'u1%' range idx_name 9848 ✅ 前缀可用
5 where name like '%u1%' index idx_name 19697 ⚠️ 全索引扫描(非 range)
6 where age=30 or city='city5' ALL NULL 19697 ❌ OR 混无索引列

最震撼的一行是 #2:同一个条件,写法不同,扫描行数 250 → 20000(80 倍)。


3. 六种失效与边界

情况 为什么 例外/边界
① 列上做运算/函数 索引存的是原值 8.0 的函数索引((col+1) 建索引)可解
② 前导模糊 %x 无法有序定位 仍可走覆盖索引扫描(#5 的 type=index)
③ 隐式类型转换 转换发生在列上才失效 #3 中字符串常量被转成数字 → 不失效
④ OR 混无索引列 只能全表 两侧都有索引 → 可能 index_merge
⑤ 联合索引跳最左列 无法定位 8.0 有 skip scan(条件有限)
⑥ 选择性太低 优化器判定全表更快 强制 force index 可验证

第 ③ 条最容易误判:"字符串 vs 数字"谁被转换,决定是否失效——where phone='138...'(列是 varchar)不失效;where varchar_col = 138(列被转数字)失效。


4. OR 的正确写法(E-S11-016)

-- ❌ city 无索引 → 全表
where age=30 or city='city5'

-- ✅ 两边都建索引(可能 index_merge)
where age=30 or city2='city5'   -- city2 有索引

判据:"OR 两侧的列都有索引吗?" 没有 → 改写为 UNION ALL。


5. 怎么验证"到底用没用索引"

手段 说明
EXPLAIN 看 type/key/rows
EXPLAIN ANALYZE(8.0.18+) 看实际执行时间与行数
force index / ignore index 强制对比
慢日志 Rows_examined 线上真实指标

判据:"rows 与返回行数差多少倍?" 差得多 → 索引没发挥作用。


6. 五个误区

误区 真相
"加了索引就一定会用" 六种情况都会失效
"like '%x%' 完全不用索引" 可走覆盖索引扫描(但收益小)
"隐式转换一定失效" 取决于转换发生在哪一侧
"OR 一定全表" 两侧都有索引可用 index_merge
"优化器总选最优" 统计信息过期会选错

7. 自检

  1. 六种失效的根因分别是什么(一句话)?
  2. 实测里函数包裹让 rows 从多少变到多少?
  3. 隐式转换"什么时候失效"?
  4. like '%x%' 的 type=index 是什么意思?
  5. 怎么验证"索引到底有没有用上"?

8. 下一篇

S11-J03 · Explain 逐列读

失效讲完,下一篇把 EXPLAIN 的每一列读懂:type 的等级、rows 的估算逻辑、Extra 的十几种值。


本篇属于系列《S11 · 数据库与 SQL》。旧文来源:A-1233/853/850/1542;扩展点 E-S11-015/016。六组对照为 MySQL 8.0.46 实测。

S11-J02 · 索引失效的六种情况
https://www.clxhxhhr.top/posts/5332/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。