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 时,就停止匹配了。

接下来的流程就是根据主键回表,判断 agesex 的条件是否同时满足,满足则返回给客户端。

由于有索引下推的优化,匹配到 name 时,不会立刻回表:

  • 先判断复合索引 index(name,age) 中的 age 是否符合条件
  • 符合条件才进行回表接着判断 sex 是否满足,否则会被过滤掉

开启 ICP,查看执行计划时,Extra 字段会有 Using index condition 说明,表示 ICP 生效,减少了回表数据。这会改善 IO 操作数,提升处理效率。

未开启 ICP 时的查询

未开启 ICP 时的查询

开启 ICP 时的查询

仅图中「红色箭头」+「对勾√」标识部分发生回表,减少 IO 操作。

开启 ICP 时的查询

ICP 注意事项

  • ICP 适用于 range, ref, eq_ref, and ref_or_null 的回表操作前过滤数据
  • 支持 InnoDBMyISAM 引擎
  • ICP 目的是减少回表读操作数(reduce the number of full-row reads),从而减少 I/O 操作
  • InnoDB 中 ICP 仅支持二级索引,不支持聚簇索引。因 InnoDB 引擎下,聚簇索引的字段信息已全部在索引中。
  • 指向子查询的查询条件无法利用 ICP
  • 函数或触发器无法利用 ICP

引用

  1. MySQL 索引下推
作者

Jakes Lee

发布于

2021-06-13

更新于

2021-11-23

许可协议

评论