最核心的 8 大索引失效原因
一、最核心的 8 大索引失效原因(必背)
1. WHERE 子句中对索引列做运算 / 函数
-- 失效SELECT * FROM user WHERE YEAR(create_time) = 2025;SELECT * FROM user WHERE id + 1 = 100;-- 生效SELECT * FROM user WHERE create_time >= '2025-01-01';SELECT * FROM user WHERE id = 99;
2. 模糊查询 LIKE 以 % 开头
-- 失效SELECT * FROM user WHERE name LIKE '%张三';-- 生效SELECT * FROM user WHERE name LIKE '张三%';
3. 使用了!= 、 <> 、 IS NOT NULL
-- 失效SELECT * FROM user WHERE name != '张三';
4. 索引列使用隐式类型转换
-- phone 是 VARCHAR(11),这样写索引失效SELECT * FROM user WHERE phone = 13800138000;-- 正确SELECT * FROM user WHERE phone = '13800138000';
5. 复合索引不满足「最左前缀原则」
(a,b,c)必须从最左边列开始用
跳过前面的列,后面索引全部失效
-- 索引 (a,b,c)WHERE c=? -- 失效WHERE b=? AND c=? -- 失效WHERE a=? AND c=? -- a 生效,b、c 失效WHERE a=? AND b=? AND c=? -- 全部生效 ✅
6. OR 连接了非索引列
-- name 有索引,age 没有 → 索引失效SELECT * FROM user WHERE name='张三' OR age=20;
7. MySQL 优化器判断:全表更快
8. 索引失效 / 损坏 / 没分析表
ANALYZE TABLE user; -- 重新分析索引
二、怎么判断索引到底有没有生效?
EXPLAIN 看结果:EXPLAIN SELECT * FROM user WHERE name='张三';
看这 2 列就够:
- type
ref/range= 索引生效 ✅ALL= 全表扫描,索引失效 ❌- key
显示索引名 = 用到索引 ✅
NULL= 没用到 ❌
三、索引不生效 快速排查口诀(背会)
索引列别运算、别函数
Like 不要 % 开头
字符串必须加引号
复合索引遵守最左前缀
Or 慎用,非索引列会破坏索引
!= <> Not Null 会导致失效
数据太少 MySQL 不走索引

