概述
Index Condition Pushdown (ICP)是MySQL用索引去表里取数据的一种优化。如果禁用ICP,引擎层会穿过索引在基表中寻找数据行,然后返回给MySQL Server层,再去为这些数据行进行WHERE后的条件的过滤。ICP启用,如果部分WHERE条件能使用索引中的字段,MySQL Server 会把这部分下推到引擎层。存储引擎通过使用索引条目,然后推索引条件进行评估,使用这个索引把满足的行从表中读取出。ICP能减少引擎层访问基表的次数和MySQL Server 访问存储引擎的次数。总之是 ICP的优化在引擎层就能够过滤掉大量的数据,这样无疑能够减少了对base table和mysql server的访问次数。
ICP的优化用于range, ref, eq_ref, and ref_or_null访问方法,当这些需要访问全表的行。这个策略可以用于INNODB和MyISAM表。
示例
表orders:
CREATE TABLE orders (
order_id INT NOT NULL PRIMARY KEY,
customer_id INT,
value INT,
order_date DATE,
KEY idx_custid_value (customer_id, value)
);
query : select * fromorders where customer_id<4 and value=290;
在没有ICP之前它是这样执行的:
1. 从索引idx_custid_value索引里面取出下一条customer_id<4的记录,然后利用主键字段读取整个行
2. 然后对这个完整的行利用value=290这个进行判断看是否符合条件
3. 从1开始重复这个过程
有了ICP之后则是这样执行的:
1. 从索引idx_custid_value索引里面取出下一条customer_id<4的记录,然后利用索引记录判断是否value=290,如果匹配执行第2步,否则第3步
2. 使用符合条件的数据order_id去主键索引里面找到这个完整行
3. 从1开始重复这个过程
ICP的限制
1. 当sql需要全表访问时,ICP的优化策略可用于range, ref, eq_ref, ref_or_null 类型的访问数据方法 。
2. 支持InnoDB和MyISAM表。
3. ICP只能用于二级索引,不能用于主索引。
4. 并非全部where条件都可以用ICP筛选。
如果where条件的字段不在索引列中,还是要读取整表的记录到server端做where过滤。
5. ICP的加速效果取决于在存储引擎内通过ICP筛选掉的数据的比例。
6. 5.6 版本的不支持分表的ICP 功能,5.7 版本的开始支持。
7. 当sql 使用覆盖索引时,不支持ICP 优化方法。
参考:https://www.cnblogs.com/zhoujinyi/archive/2013/04/16/3016223.html
