MySQL索引下推(ICP)优化原理
什么是MySQL索引下推(Index Condition Pushdown, ICP)?ICP是如何减少回表次数的?在什么情况下ICP生效或者不生效?请用具体例子说明。
回答
专业代码师
什么是索引下推(ICP):
- MySQL 5.6+引入的优化,将WHERE条件中部分过滤操作下推到存储引擎层
- 在二级索引遍历时,直接对索引列做WHERE条件过滤
- 减少回表次数(只有符合条件的记录才回表查完整数据)
无ICP时的流程:
假设有联合索引(name, age),查询:
SELECT * FROM t WHERE name LIKE '张%' AND age = 20
- 通过二级索引找到所有name='张%'的记录(假设1000条)
- 对这1000条逐个回表(随机IO)
- 在Server层过滤age=20(假设只有10条符合)
- 做了990次无用的回表
有ICP时的流程:
- 通过二级索引找到name='张%'的记录
- 在存储引擎层,直接检查索引中的age字段是否为20
- 只有age=20的记录才回表(只回表10次)
- 节省了990次随机IO
ICP生效条件:
- 使用二级索引(联合索引)
- WHERE条件中的列被索引覆盖(在索引列中)
- 不能是聚簇索引(聚簇索引已经包含完整数据,不需要ICP)
- 存储引擎需支持ICP(InnoDB和MyISAM支持)
- 不能是范围查询的右侧列(如
a > 10 AND b = 1,b无法下推)
ICP不生效的情况:
- 查询使用覆盖索引(无需回表,ICP无意义)
- WHERE条件使用了函数或运算
- 使用子查询或联表查询(某些情况)
- 索引列的数据类型不匹配(隐式转换)
查看是否使用ICP:
- EXPLAIN输出中Extra列为
Using index condition表示使用了ICP - 可通过
SET optimizer_switch = 'index_condition_pushdown=off'关闭ICP对比性能