索引失效场景
2026/6/16 12:45:52 网站建设 项目流程

1. 最左前缀原则失效

假设联合索引:

CREATE INDEX idx_abc ON user(name, age, city);

索引顺序:

name → age → city

可以走索引

where name='Tom'
where name='Tom' and age=20
where name='Tom' and age=20 and city='BJ'

不能走索引

where age=20
where city='BJ'
where age=20 and city='BJ'

因为缺少最左列:

name

B+Tree 无法定位起始位置。


2. 索引列使用函数

例如:

where YEAR(create_time)=2025

索引:

create index idx_time on user(create_time);

失效原因:

数据库需要先计算:

YEAR(create_time)

B+Tree 存的是:

2025-06-16 10:00:00

不是:

2025

无法直接利用索引。


优化:

where create_time >= '2025-01-01' and create_time < '2026-01-01'

3. 索引列参与运算

例如:

where age + 1 = 20

索引:

idx_age(age)

失效。

因为:

数据库需要先算 age+1

无法直接使用 B+Tree。


改为:

where age = 19

4. 隐式类型转换

表:

phone varchar(20)

索引:

idx_phone(phone)

查询:

where phone = 13800138000

注意:

phone 是 varchar 条件是数字

MySQL 可能会:

CAST(phone AS SIGNED)

变成:

函数作用于索引列

导致索引失效。


正确写法:

where phone='13800138000'

5. LIKE 左模糊查询

索引:

idx_name(name)

可以走索引

where name like 'Tom%'

因为:

Tom Tom1 Tom2 Tom3

范围明确。


不能走索引

where name like '%Tom'

或者:

where name like '%Tom%'

因为:

前缀未知

B+Tree 无法定位起点。

只能全表扫描。


6. 范围查询后面的列失效

联合索引:

(name, age, city)

查询:

where name='Tom' and age > 20 and city='BJ'

执行到:

age > 20

之后:

city

无法继续利用索引匹配。

原因:

范围查询会破坏索引连续性。


口诀:

范围之后全失效

(这里是指索引匹配能力,不是一定完全不用索引)


7. OR 导致索引失效

例如:

where name='Tom' or salary=10000

如果:

name有索引 salary没索引

MySQL 很可能:

直接全表扫描

因为:

走索引 + 全表扫描

成本可能更高。


优化:

UNION ALL

拆开。


8. 使用 != 或 <>

例如:

where age != 20

或者:

where age <> 20

数据库发现:

大部分数据都满足

需要扫描大量记录。

优化器经常选择:

全表扫描

9. NOT IN

例如:

where id not in (1,2,3)

通常返回:

绝大部分数据

优化器可能放弃索引。


10. NOT EXISTS

类似:

where not exists(...)

很多场景索引利用率较低。


11. 数据量太小

例如:

10条数据

即使有索引:

全表扫描

可能比:

索引查找+回表

更快。

优化器会主动放弃索引。


12. 查询结果占比过高

例如:

where gender='男'

表:

1000万数据

其中:

900万男

即使有索引:

idx_gender

优化器可能认为:

回表900万次

成本太高。

直接:

全表扫描

更划算。


高频总结

MySQL 索引失效常见场景包括:

  1. 不满足联合索引最左前缀原则;
  2. 对索引列使用函数、计算或表达式;
  3. 隐式类型转换;
  4. LIKE 以%开头;
  5. 联合索引中范围查询后的列无法继续利用索引;
  6. OR 一侧无索引;
  7. 使用!=<>NOT INNOT EXISTS
  8. 数据量过小或查询结果占比过高时,优化器主动放弃索引。

本质上,索引失效的原因要么是B+Tree 无法利用有序性定位数据,要么是优化器评估后认为走索引成本高于全表扫描

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询