概念
索引条件下推是对使用索引从表中检索行的一种优化。如果不使用icp,存储引擎先遍历索引然后去基表中去定位所需要的行,并将其返回给Mysql服务器,然后服务器进行where条件的过滤。使用到icp后,如果where的部分列可以仅使用索引中的列来过滤,则mysql服务器会将这部分条件下推到存储引擎,存储引擎使用索引条目来计算已推入的索引条件,只有满足这个条件,才从表中读取行。从而减少存储引擎访问表的次数和mysql服务器访问存储引擎的次数
需要满足的条件
1、当range、ref、eq_ref和ref_or_null访问方法需要访问全表的行时(全表的行指的是访问索引查出来的所有行)
2、存储引擎是innodb或者是myisam
3、innodb中只能被用于二级索引
4、引用子查询不能下推
5、涉及存储功能的条件不能下推。存储引擎无法调用存储的功能
6、触发条件不能下推
总结
使用索引条件下推时 EXPLAN中的extra列中将出现 Using index condition。5.6中只要where条件中能使用到索引就会出现这个Using index condition,但像单值索引或可以说只能使用到一个索引的时候就不必进行索引条件下推优化,因为它根本没有下一个索引列可进行过滤,5.7中对此进行了优化,这种情况就不会出现 Using index condition。
根据索引下推原理,我感觉它主要就是优化了联合索引的范围查询导致索引失效和跳字段导致索引失效的问题。
5.7效果比较明显,仅使用5.7举个例子
创建联合索引
create index idx_name_age_position on employees(name,age,position)
举例一:

关闭下推再次查看

举例2:

关闭下推再次查看
猜测
有个现象是,开启索引下推和关闭索引下推,explain中rows的预估扫描行数是一样的,理论上下推会减少对表的扫描行数,这个就有些矛盾了。
我猜测的是,rows只是mysql预估的扫描行数,预估的时候可能没有考虑下推优化,只是根据使用到的索引进行预估的。具体是不是这样那就需要研究mysql源码了(俺是不会去研究的)
参考文章
https://dev.mysql.com/doc/refman/5.7/en/index-condition-pushdown-optimization.html
本文介绍了MySQL索引条件下推优化,它可减少存储引擎和服务器的访问次数。还阐述了使用该优化需满足的条件,如特定访问方法、存储引擎类型等。此外,给出创建联合索引示例,并对开启和关闭索引下推时explain中rows预估扫描行数相同的现象进行猜测。
&spm=1001.2101.3001.5002&articleId=110479101&d=1&t=3&u=7b2088349bc447e4a3a2ce2c734b7158)
2543

被折叠的 条评论
为什么被折叠?



