SQL索引并非建了就生效,失效主因是破坏有序性、确定性或原始值匹配;函数操作、类型不匹配、OR含非索引字段及联合索引顺序不当均会导致全表扫描。

SQL索引不是“建了就一定生效”,很多看似合理的查询,实际执行时却绕过索引走全表扫描。根本原因在于:索引(尤其是B+树)依赖有序性、确定性、原始值匹配——一旦破坏这三点,优化器就无法安全、高效地使用它。
对索引字段使用函数(如 YEAR()、SUBSTR()、UPPER())、运算(如 age + 1 = 25)或类型转换(如 CAST()),会导致索引失效。
WHERE YEAR(create_time) = 2023 或 WHERE name LIKE CONCAT('%', ?)
WHERE create_time >= '2023-01-01' AND create_time
LIKE 匹配是否走索引,取决于通配符位置。B+树按字符串前缀排序,只能高效支持“左对齐”查找。
LIKE '%张'、LIKE '%三%'(首部含 %)LIKE '张%'(前缀匹配)、LIKE '张_明'(固定长度通配)LIKE '张%' ESCAPE '\' 中转义符不影响索引使用,但需确保语义清晰复合索引 (a, b, c) 的 B+ 树叶子节点按 a → b → c 排序。跳过左侧列,后续列无法定位。
WHERE b = 2 AND c = 3(没用 a)、WHERE a > 10 AND c = 'x'(c 在范围列右侧)WHERE a = 1、WHERE a = 1 AND b > 5、WHERE a = 1 AND b = 2 AND c LIKE 'y%'
当字段类型与查询值类型不一致,MySQL 自动做类型转换,导致索引列被“包装”成临时表达式,无法比对原始索引值。
VARCHAR 字段查数字:WHERE user_no = 12345(实际字段是字符串)WHERE user_no = '12345';INT 字段加引号一般仍可用索引(MySQL 会反向转为整型)EXPLAIN 查看 type 是否为 ref/range,key 是否显示索引名优化器面对 OR 时,只要任一条件无法利用索引,往往放弃整个索引路径,选择全表扫描更“稳妥”。
WHERE id = 100 OR username = 'tom'(仅 id 有索引)username 加索引UNION ALL 拆分:(SELECT ... WHERE id = 100) UNION ALL (SELECT ... WHERE username = 'tom')
id > 10 OR id ),也可能因优化器判断低效而弃用索引
除上述高频场景外,以下情况也常导致索引“静默失效”:
INCLUDE NULL),IS NULL 可能走索引,但 IS NOT NULL 在高 NULL 率下常被优化器跳过!=、、NOT IN、NOT EXISTS 因结果集分散,优化器倾向全表扫描ANALYZE TABLE,优化器基于错误基数选错执行计划以上就是SQL索引失效原因有哪些_常见错误场景全面总结【教程】的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号