MySQL索引失效的场景

197 阅读2分钟

MySQL索引失效的场景主要包括以下几种情况,这些情况会导致查询无法利用索引,从而降低查询性能:

1. 不符合最左前缀原则

  • 问题:联合索引中,查询条件未包含最左侧的列,索引会失效。
    示例

    -- 假设有联合索引 (a, b, c)
    SELECT * FROM table WHERE b = 1 AND c = 2;  -- 索引失效
    SELECT * FROM table WHERE a = 1 AND b = 2;  -- 索引生效
    

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

  • 问题:对索引列进行函数操作(如YEAR(date_column))或数学运算(如id + 1 = 10)会导致索引失效。
    示例

    SELECT * FROM users WHERE YEAR(create_time) = 2023;  -- 索引失效
    

3. 隐式类型转换

  • 问题:查询条件与索引列数据类型不一致(如字符串与数值比较),MySQL会放弃索引。
    示例

    SELECT * FROM users WHERE age = '25';  -- 若age是INT类型,索引失效
    

4. 使用LIKE以通配符开头

  • 问题LIKE条件以%开头(如'%abc')无法使用索引。
    示例

    SELECT * FROM products WHERE name LIKE '%apple%';  -- 索引失效
    SELECT * FROM products WHERE name LIKE 'apple%';   -- 索引生效
    

5. 使用OR连接非索引列

  • 问题OR连接的字段中有一个未建索引,整个查询会全表扫描。
    示例

    SELECT * FROM users WHERE name = '张三' OR height = 175;  -- 若height无索引,索引失效
    

6. IS NULLIS NOT NULL

  • 问题:索引不存储NULL值,IS NULL可能导致全表扫描。
    示例

    SELECT * FROM users WHERE address IS NULL;  -- 可能索引失效
    

7. 不等于操作(!=<>)​

  • 问题!=<>操作通常无法利用索引。
    示例

    sql
    复制
    SELECT * FROM users WHERE name != '张三';  -- 索引失效
    

8. 数据量过小或选择性差

  • 问题:当表数据量极少或索引列重复值过多(如性别字段),优化器可能放弃索引。
    示例

    SELECT * FROM users WHERE gender = 'male';  -- 若gender值重复率高,索引可能失效
    

9. 使用ORDER BY非索引列

  • 问题:排序字段无索引时,MySQL需额外排序操作。
    示例

    SELECT * FROM users ORDER BY name;  -- 若name无索引,性能下降
    

10. 统计信息不准确

  • 问题:索引统计信息过期可能导致优化器误判。
    解决方案:定期执行ANALYZE TABLE更新统计信息。

总结

索引失效的核心原因是破坏了索引的有序性优化器成本计算认为全表扫描更快。建议通过EXPLAIN分析查询计划,针对性优化索引设计或SQL写法。