索引条件下推(Index Condition Pushdown,ICP)是MySQL 5.6+版本中的新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式。
与之名称相似的还有引擎条件下推(engine_condition_pushdown=on),引擎条件下推只用于NDB引擎,开启后时按照WHERE条件过滤后的数据发送到SQL节点来处理,不开启所有数据节点的数据都发送到SQL节点来处理。
下面之说innodb的索引条件下推
ICP是对联合索引进行二次过滤之后回表。用于二级索引的range、 ref、 eq_ref或ref_or_null扫描,如果部分where条件能使用索引的字段,MySQL Server会把这部分下推到引擎层,可以利用index过滤的where条件在存储引擎层进行数据过滤。
一个SQL执行需要三个步骤:
1、Index Key(>=first key and <=last>
2、Index Filter;(过滤出我们要扫描的数据)
3、Table Filter(WHERE条件里面不含索引的字段进行过滤)
【ICP原理】:
ICP的原理就是将可以利用索引筛选的where条件在存储引擎一侧进行筛选,而不是将所有index access的结果取出放在Server端进行where筛选。本质就是将Index Filter下推到存储引擎层处理,以减少回表/随机IO次数,降低storage层返回给sever层的结果集大小。直接就去掉了不满足Index Filter条件的记录,省去了回表和传递到server层的成本。
关闭ICP的流程如下(这两张图是网上的,侵权联系我就删掉了):
开启ICP的流程如下
索引下推的注意事项:
1、只能用于二级索引(Secondary Index),其中一部分索引无法使用的时候。
2、EXPLAIN显示的执行计划中type字段值(join 类型)为range、 ref、 eq_ref或者ref_or_null,且查询需要访问表的整行数据,即不能直接通过二级索引的元组数据获得查询结果(索引覆盖,Using Index)。
3、ICP可以用于MyISAM和InnnoDB存储引擎,包括分区表InnoDB和 MyISAM表(MySQL 5.6中的分区表不支持ICP;MySQL 5.7已解决此问题。)。
4、在虚拟生成的列上创建的二级索引不支持ICP。InnoDB 支持虚拟生成的列上的二级索引。
5、引用子查询的条件不能下推。
6、涉及存储功能的条件不能下推。存储引擎无法调用存储的功能。
7、触发条件不能下推。