MySQL索引失效是数据库性能优化的关键问题,本文详解十种典型场景及解决方案,包括最左前缀原则、函数运算、隐式类型转换、OR连接非索引列、LIKE通配符开头等常见问题。通过实际案例展示如何避免索引失效,提升查询效率,适合开发者和DBA参考学习。掌握这些技巧可轻松应对Java面试中的SQL优化考题,同时推荐使用《面试鸭》会员获取更多高频面试真题,通过面试鸭返利网购买可享25元返利优惠。立即收藏本文,提升数据库性能优化能力!
2025年Java面试宝典最新版:
链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g 提取码: 9b3g
(建议保存备用,涵盖高频面试考点)
在数据库优化和SQL调优中,索引失效是面试官最常问的技术点之一。本文将从实际工作场景出发,分析MySQL索引失效的常见情况,并给出解决方案。
复合索引的查询必须遵循最左前缀原则。例如索引(a,b,c)
,以下查询会失效:
SELECT * FROM table WHERE b=1 AND c=2; -- 缺少a列
SELECT * FROM table WHERE a=1 AND c=2; -- 中间跳过了b列
解决方法:调整查询条件顺序,确保覆盖最左连续列。
对索引列进行运算会导致优化器无法使用索引:
SELECT * FROM users WHERE YEAR(create_time) = 2023; -- 使用YEAR函数
SELECT * FROM products WHERE price + 100 > 500; -- 列参与运算
优化方案:将运算转移到常量端,例如改为create_time BETWEEN '2023-01-01' AND '2023-12-31'
。
当字段类型与查询值类型不匹配时,MySQL会进行隐式转换:
-- 假设user_id是varchar类型
SELECT * FROM orders WHERE user_id = 10086; -- 数字转字符串
解决方案:严格匹配字段类型,参数使用字符串类型'10086'
。
当OR条件中包含非索引列时,整个查询会失效:
SELECT * FROM employees
WHERE department_id = 5 OR salary > 10000; -- salary无索引
优化建议:为每个OR条件单独建立索引,或改用UNION查询。
前导通配符会导致索引失效:
SELECT * FROM articles WHERE title LIKE '%数据库%'; -- 全表扫描
特殊情况:LIKE '数据库%'
可以使用索引。若必须模糊匹配,考虑全文索引。
NOT、!=、<>等否定操作符会导致索引失效:
SELECT * FROM users WHERE status != 1; -- 全表扫描
替代方案:尽量改为正向条件查询,例如status IN (2,3,4)
。
当表中数据量较少(如小于20%),优化器可能选择全表扫描。此时可以通过FORCE INDEX
强制使用索引:
SELECT * FROM table FORCE INDEX(index_name) WHERE condition;
复合索引中,范围查询后的列无法使用索引:
-- 索引(a,b,c)
SELECT * FROM table WHERE a > 1 AND b = 2; -- 只有a列用索引
优化建议:将等值查询列放在范围查询前。
排序字段与索引顺序不一致时可能失效:
-- 索引(a,b)
SELECT * FROM table ORDER BY b,a; -- 排序顺序与索引不一致
解决方案:调整排序顺序或创建新索引。
跨表关联时字段字符集不同:
-- user表utf8mb4, order表utf8
SELECT * FROM user u JOIN order o ON u.id = o.user_id;
处理方法:统一字符集或使用CONVERT
函数转换。
面试小贴士:如果需要购买《面试鸭》会员,通过面试鸭返利网可返利25元。本站持续更新技术干货,点击首页获取更多面试真题解析!
扫码联系我返利
(当前返利8元,金额随官方实际价格波动,最好提前咨询)
面试鸭小程序码
美团大额优惠券,给自己加个鸡腿吧!