索引下推

索引下推(Index Condition Pushdown,简称 ICP) 是MySQL 5.6版本中提供的一项索引优化功能,它允许存储引擎在索引遍历过程中,执行部分WHERE字句的判断条件,直接过滤掉不满足条件的记录,从而减少回表次数,提高查询效率。

在没有索引下推时,查询流程大概是这样的:

1)通过索引找到“可能符合”的记录(只按能用到的索引列判断)
2)回表(根据主键去聚簇索引查整行数据)
3)在 Server 层判断剩余的 where 条件
4)丢弃不符合的

问题在于:**有些条件明明只依赖索引字段,却没有在索引扫描阶段就过滤掉,而是傻乎乎回表之后才判断。**这就增加了大量随机IO。

举例:

1
2
3
4
5
6
7
8
9
CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(20),
age INT,
INDEX idx_name_age(name, age)
);

SELECT * FROM user
WHERE name LIKE 'Li%' AND age = 18;

联合索引是 (name, age)。

没有索引下推时:

  • 通过 name LIKE ‘Li%’ 定位索引范围
  • 把所有 name 符合的记录主键取出来
  • 每条都回表
  • 再判断 age = 18

但 age 本来就在索引里啊!为什么不提前判断?

这就是 ICP 的作用:

开启索引下推后:

  • 在扫描索引时
  • 直接在存储引擎层判断 age = 18
  • 只有满足条件的记录才回表

于是:

回表次数减少
磁盘 IO 减少
查询更快


一句话概括:

索引下推 = 在索引遍历阶段就提前执行 where 条件过滤,减少回表次数。


再说几个关键点(面试常考):

1)只适用于二级索引
因为聚簇索引本来就已经是整行数据,不存在“回表”。

2)适用于范围查询
等值查询本来就很精准,收益不明显。

3)MySQL 5.6 之后默认开启
可以通过:

1
SHOW VARIABLES LIKE 'optimizer_switch';

查看是否开启 index_condition_pushdown。