上一篇 下一篇 分享链接 返回 返回顶部

数据库索引失效的常见场景与规避

发布人:用户运营 | 723 发布时间:2小时前 阅读量:1

该文章由AI生成,仅为SEO优化测试,相关内容不保证准确!!!

引言

“索引建了,查询还是慢”——多数情况不是索引没用,而是写法让索引失效了。MySQL 优化器在特定条件下会放弃走索引,以下七种场景覆盖了 90% 的案例。

1. 违反联合索引的最左前缀

联合索引 (a,b,c) 只有在查询条件包含 a(或 a,b、a,b,c)时才能使用。查询条件只有 b 或 c 时索引失效。规避:按查询模式设计列顺序,把最常用的过滤列放最左;或为高频组合单独建索引。

2. 对索引列使用函数或运算

WHERE YEAR(create_time)=2026、WHERE id+1=100 这类写法会让索引失效,因为对列做了运算后优化器无法使用 B+ 树的有序性。改写为范围查询:WHERE create_time >= '2026-01-01' AND create_time < '2027-01-01'、WHERE id=99。

3. 隐式类型转换

列是 varchar 却用数字查询:WHERE phone=13800000000,MySQL 会把列转成数字比较,索引失效。必须写成 WHERE phone='13800000000'。反向(列是 int 传字符串)通常不影响,但仍建议类型一致。

4. 前导模糊查询

LIKE '%关键词' 无法使用 B+ 树索引;LIKE '关键词%' 可以。确需全文检索时用 FULLTEXT 索引或 Elasticsearch,而不是硬用 LIKE。

5. OR 连接非索引列

WHERE a=1 OR b=2 中只要 b 没索引,整条查询就放弃索引(优化器需同时扫两个条件)。改写为 UNION 两条各自的索引查询,或给 b 也建索引。注意 5.6+ 的 index_merge 有时能救,但不稳定,不应当依赖。

6. NOT IN / != / IS NOT NULL 的局限

这些否定条件在多数场景无法有效利用索引(范围不连续)。如果业务允许,改写为 IN 具体值列表,或用覆盖索引减少回表影响。

7. 优化器判断不走索引更快

表数据量小、或查询要返回大部分行时,优化器认为回表成本高于全表扫描,会主动放弃索引——这不是 bug。此时可考虑覆盖索引(把查询列都放进索引),或用 FORCE INDEX 强制(慎用,数据分布变化后会变慢)。

排查方法

任何“慢 SQL”先 EXPLAIN:type 为 ALL 且 key 为 NULL 就是失效;再用 SHOW INDEX FROM 表名 核对索引结构,对照以上七条逐项排查。改写后对比 rows 值确认生效。

总结

索引失效的本质是“写法破坏了索引的有序性或最左前缀”。牢记七场景:最左前缀、列上函数、隐式转换、前导模糊、OR 非索引列、否定条件、优化器权衡。写 SQL 时多想一步,比事后优化省力得多。

目录结构
全文
微信公众号 微信公众号
抖音官方账号 抖音官方账号
CSDN官方账号 CSDN官方账号
经营主体身份码 经营主体身份码
电子邮箱: admin@2v8.cn

本页面部分展示信息可能存在偏差/错误