EXPLAIN 是查看 MySQL 索引是否生效的唯一可靠方式;需重点关注 key(实际使用索引名,NULL 表示未走索引)和 Extra 字段(如 Using index 表示覆盖索引,Using filesort 表示索引失效)。

用 EXPLAIN 看执行计划,这是唯一可靠方式
MySQL 不会告诉你“索引用了没”,只会在执行时悄悄决定——而 EXPLAIN 是你唯一能看清它怎么想的窗口。直接在查询前加 EXPLAIN,观察 key 和 Extra 字段:
-
key显示实际使用的索引名(为NULL就代表没走索引) -
Extra出现Using index:走了覆盖索引,最快;出现Using where; Using index:索引有效但需回表;出现Using filesort或Using temporary:大概率索引没生效或设计不合理 - 别信
possible_keys——它只是“可能用”,不代表真用
LIKE 模糊查询中,% 放哪儿决定索引生死
不是所有 LIKE 都慢,关键看通配符位置。MySQL 只能利用 B+Tree 的有序前缀匹配能力:
-
WHERE column LIKE 'abc%'→ ✅ 索引生效(等价于范围查找) -
WHERE column LIKE '%abc'→ ❌ 全表扫描(无法定位起始点) -
WHERE column LIKE '%abc%'→ ❌ 同样失效,除非你用覆盖索引 +SELECT仅查索引列(Extra显示Using index) - 字符串字段查询不加引号,比如
WHERE status = 1(而status是VARCHAR)→ 自动类型转换,索引失效
联合索引失效最常见原因:WHERE 跳过了最左列或中间断层
联合索引 (a, b, c) 不是三个独立索引,而是一颗按字典序排列的 B+Tree。它的使用有硬约束:
- 必须从
a开始:没有a = ?或a IN (...),整个索引作废 - 中间不能断:有
a = ? AND c = ?(跳过b),则只有a生效,c无效 -
b上用了范围条件(>、BETWEEN、IN等),c就不再走索引(但a和b仍有效) - 写成
WHERE b = ? AND a = ?没关系——顺序不影响,优化器会自动调整
OR 条件下,所有字段都得有索引才安全
OR 是索引杀手,除非你能保证“或”的每一侧字段都有可用索引:
-
WHERE phone = '138...' OR age = 25→ 若age无索引,整个条件放弃索引,全表扫描 - 修复方法不是加一个复合索引,而是分别建单列索引:
INDEX idx_phone(phone)+INDEX idx_age(age) - 注意:MySQL 5.7+ 支持 Index Merge,但依赖数据分布和优化器判断,不可强依赖;宁可拆成
UNION或重写为IN子句 - 还有个隐形陷阱:
WHERE status != 'done'或IS NULL,在低基数字段(如只有 2–3 个值)上,MySQL 往往直接弃用索引,因为扫全表反而更快
真正难的不是知道规则,而是当 EXPLAIN 显示没走索引时,要立刻判断:是写法问题?数据分布导致优化器放弃?还是索引本身设计就漏了关键路径?多看几遍 rows 和 filtered 值,比背口诀管用得多。










