MySQL索引失效是影响查询性能的常见问题,以下是主要失效场景及原因分析:
1. 违反最左前缀原则
-
复合索引未按定义顺序使用(如索引
(a,b,c)
但查询仅用b
或c
)会导致索引部分或完全失效。 -
例外:MySQL 8.0+支持索引跳跃扫描,当首列唯一值较少时可能绕过此限制。
2. 对索引列使用函数或运算
-
任何函数(如
YEAR(date_column)
、LOWER(name)
)或算术运算(如price+1=100
)都会破坏索引的有序性,导致全表扫描。
3. LIKE模糊查询不当
-
左模糊(
LIKE '%abc'
)或全模糊(LIKE '%abc%'
)会使索引失效,仅右模糊(LIKE 'abc%'
)可利用索引。 -
特例:覆盖索引(查询字段全在索引中)时,左模糊可能仍走索引扫描。
4. 隐式类型转换
-
字符串索引列与数字比较(如
varchar_col=123
)会触发类型转换,导致索引失效。 -
多表联查时字段字符集不一致(如
utf8
与utf8mb4
)同样会引发此问题。
5. OR条件使用不当
-
OR连接的列若不全有索引(如
name
有索引但age
无索引),优化器会放弃索引选择全表扫描。 -
优化方案:改用
UNION ALL
拆分查询。
6. 范围查询中断索引
-
联合索引中若某列使用范围查询(
>
、<
、BETWEEN
),其右侧列的索引会失效。 -
示例:索引
(a,b,c)
,条件a=1 AND b>10 AND c=2
仅能利用a
和b
的索引。
7. NULL值处理
-
IS NULL
/IS NOT NULL
可能导致索引失效,尤其当NULL值占比高时。 -
原因:B+树索引不存储NULL值的有序信息。
8. 负向查询操作符
-
!=
、<>
、NOT IN
、NOT LIKE
等负向条件通常无法利用索引。
9. 数据特征影响
-
低区分度列(如性别字段)即使有索引,优化器也可能选择全表扫描。
-
小表查询:数据量过小时直接全表扫描可能更快。
10. 统计信息不准确
-
索引统计信息过期会导致优化器误判,需定期执行
ANALYZE TABLE
更新统计。