MySQL 索引下推
在 MySQL 5.6 版本后加入的新特性索引下推(Index Condition Pushdown)。 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
Index Filter 与 Table Filter 分离,Index Filter 下降到 InnoDB 的索引层面进行过滤,减少了回表与返回 MySQL Server 层的记录交互开销,提高了 SQL 的执行效率。
复合索引:index(name,age) ,然后有一条 SQL 如下:
1 | select * from user where name like '张%' and age = 10 and sex = 'm'; |
根据复合索引的最左前缀匹配原则,MySQL 匹配到复合索引 index(name,age)
的 name
时,就停止匹配了。
接下来的流程就是根据主键回表,判断 age
和 sex
的条件是否同时满足,满足则返回给客户端。
由于有索引下推的优化,匹配到 name
时,不会立刻回表:
- 先判断复合索引
index(name,age)
中的age
是否符合条件 - 符合条件才进行回表接着判断
sex
是否满足,否则会被过滤掉
开启 ICP,查看执行计划时,Extra 字段会有 Using index condition
说明,表示 ICP 生效,减少了回表数据。这会改善 IO 操作数,提升处理效率。
未开启 ICP 时的查询
开启 ICP 时的查询
仅图中「红色箭头」+「对勾√」标识部分发生回表,减少 IO 操作。
ICP 注意事项
- ICP 适用于
range, ref, eq_ref, and ref_or_null
的回表操作前过滤数据 - 支持
InnoDB
和MyISAM
引擎 - ICP 目的是减少回表读操作数(
reduce the number of full-row reads
),从而减少 I/O 操作 InnoDB
中 ICP 仅支持二级索引,不支持聚簇索引。因InnoDB
引擎下,聚簇索引的字段信息已全部在索引中。- 指向子查询的查询条件无法利用 ICP
- 函数或触发器无法利用 ICP