mysql 索引失效的场景

发布于:2025-07-16 ⋅ 阅读:(17) ⋅ 点赞:(0)

思考

最左匹配

join字符集

函数

null @定义字段 not null default ""

or @union all

like

字段区分度不大

+++++

!=

not in @between 

varchar类型数字型,查询不是字符串查询

MySQL 索引失效的常见场景

MySQL 索引失效会导致查询性能急剧下降,以下是索引失效的主要场景及其原理分析:

1. 违反最左前缀原则

场景:复合索引未从最左列开始使用

sql

-- 复合索引为 (a, b, c)
WHERE b = 1 AND c = 2  -- 索引失效
WHERE a = 1 AND c = 2  -- 只用到a列索引

原理:复合索引按照从左到右的顺序建立B+树结构

2. 对索引列进行计算或函数操作

场景:对索引字段进行运算或函数处理

sql

-- 索引列:create_time
WHERE YEAR(create_time) = 2023  -- 索引失效
WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31'  -- 有效

-- 索引列:age
WHERE age + 1 > 20  -- 索引失效
WHERE age > 19  -- 有效

3. 使用不等于(!= 或 <>)

场景:使用不等于条件

sql

-- 索引列:status
WHERE status != 1  -- 索引失效

例外:覆盖索引时可能仍会使用索引

4. 使用 IS NULL 或 IS NOT NULL

场景:判断NULL值

sql

-- 索引列:name
WHERE name IS NULL  -- 可能失效(取决于数据分布)

优化:设置默认值替代NULL

5. 使用LIKE以通配符开头

场景:模糊查询

sql

-- 索引列:title
WHERE title LIKE '%关键字%'  -- 索引失效
WHERE title LIKE '关键字%'   -- 可以使用索引

6. 隐式类型转换

场景:字段类型与条件值类型不一致

sql

-- 索引列:mobile(varchar)
WHERE mobile = 13800138000  -- 索引失效(数字转字符串)
WHERE mobile = '13800138000'  -- 有效

7. 使用OR条件不当

场景:OR连接非索引列

sql

-- 索引列:a
WHERE a = 1 OR b = 2  -- 索引失效(如果b无索引)

优化:改用UNION ALL

sql

SELECT * FROM table WHERE a = 1
UNION ALL
SELECT * FROM table WHERE b = 2

8. 索引列使用NOT IN

场景:否定条件查询

sql

-- 索引列:id
WHERE id NOT IN (1, 2, 3)  -- 索引失效

替代方案

sql

WHERE id < 1 OR id > 3  -- 可能使用索引

9. 数据分布不均匀

场景:索引列值区分度低

sql

-- 索引列:gender(只有'M','F'两种值)
WHERE gender = 'M'  -- 可能放弃索引(全表扫描更快)

解决方案:建立复合索引提高区分度

10. 使用ORDER BY不当

场景:排序字段与索引顺序不一致

sql

-- 索引(a, b)
ORDER BY b, a  -- 索引失效

11. JOIN条件字符集不匹配

场景:关联字段字符集不同

sql

-- table1.utf8_col JOIN table2.latin1_col
-- 索引失效

12. 索引列使用表达式

场景:索引列参与表达式

sql

-- 索引列:price
WHERE price * 0.8 > 100  -- 索引失效
WHERE price > 100 / 0.8  -- 有效

检测索引是否失效的方法

  1. EXPLAIN分析

    sql

    EXPLAIN SELECT * FROM table WHERE ...

    查看type列:

    • ref/range:使用索引

    • ALL:全表扫描

  2. 开启优化器跟踪

    sql

    SET optimizer_trace="enabled=on";
    SELECT * FROM table WHERE ...;
    SELECT * FROM information_schema.optimizer_trace;

网站公告

今日签到

点亮在社区的每一天
去签到