Index Condition Pushdown(ICP)是针对mysql使用索引从表中检索行数据时的一种优化方法。
原理:
在没有ICP特性之前,存储引擎根据索引去基表查找并将数据返回给mysql server,mysql server再根据where条件进行数据过滤。
有了ICP之后,在取出索引的同时,判断是否可以根据索引中的列进行where条件过滤,也就是将where的部分过滤操作放在了存储引擎层。这样就会减少上层sql层对记录的获取。
当sql使用覆盖索引时,不支持ICP优化方法。
ICP优化支持range、ref、eq_ref、ref_or_null类型的查询。查询优化器会给出相应的提示:Using index condition。当开启ICP后,在执行计划的extra列会显示:Using index condition。
ICP支持innodb、myisam表。对于innodb表,ICP只是用于辅助索引。
在5.6中,ICP不支持分区表。这个问题在mysql 5.7中得到解决。
优化器使用ICP时,server层将会把能够通过使用索引进行评估的where条件下推到storage engine层。数据访问和提取过程如下:
1) storage engine从索引中读取下一条索引元组。
2) storage engine使用索引元组评估下推的索引条件。如果没有满足where条件,storage engine将会处理下一条索引元组(回到上一步)。只有当索引元组满足下推的索引条件的时候,才会继续去基表中读取数据。
3) 如果满足下推的索引条件,storage engine通过索引元组定位基表的行和读取整行数据并返回给server层。
4) server层评估没有被下推到storage engine层的where条件,如果该行数据满足where条件则使用,否则丢弃。
没有ICP之前:
开启ICP之后,就变成:
默认是开启ICP的,手动开启/关闭ICP:
set
optimizer_switch =
'index_condition_pushdown=off'
;
set
optimizer_switch =
'index_condition_pushdown=on'
;
测试过程
1.环境准备
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
2.开启ICP后进行测试
1 2 3 4 5 | |
3.关闭ICP后进行测试
1 2 3 4 5 6 | |
4.结果比较
开启ICP后的执行计划:执行计划中extra部分的内容是"using index condition"
1 2 3 4 5 6 | |
关闭ICP后的执行计划:执行计划中extra部分的内容是"using where"
1 2 3 4 5 6 | |
开启ICP后的profile内容:Sending data部分的值是0.000212s
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
关闭ICP后的profile内容:Sending data部分的值是0.010990s
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
其它:
当sql使用覆盖索引时,不支持ICP优化方法
1 2 3 4 5 6 7 8 9 10 11 12 | |