索引下推(Index Condition Pushdown)

索引下推(Index Condition Pushdown)

1. 简介:

ICP是一项针对MySQL从表中使用索引检索行的优化措施。
基于MySQL5.6及以后的版本才支持ICP

2. 开启ICP优化前后的区别

关闭ICP:

存储引擎从基表中通过遍历索引定位数据行,然后将检索结果返回给MySQL服务器,
最由MySQL服务器过滤【where】中的条件。

开启ICP:

如果只能使用索引列来过滤【where】中的部分条件,MySQL服务器将会把这一部分
的【where】条件下推到存储引擎。然后存储引擎通过索引条目来过滤下推的索引
条件,​并且在只有条件满足的情况下,才会从表中取数据。

3. ICP优点:

ICP可以有效减少存储引擎访问基表的次数,以及MySQL服务器访问存储引擎的次数。

4. ICP的适用性取决于以下条件:

1.当需要访问表的全量数据时,ICP用于【range】、【ref】、【eq_ref】和
  【ref_or_null】的访问方法;
2.ICP可以用于InnoDB和MyISAM的表,也包括分区的InnoDB和MyISAM的表;
3.对于InnoDB表,ICP仅适用于二级索引,ICP的目标是减少读取全量数据的次数,
  从而减少I/O操作。
  对于InnoDB聚簇索引,完整的记录已经被读取到InnoDB的缓冲区。在这种情况
  下使用ICP不会减少I/O;
4.InnoDB在虚拟生成的列上是支持二级索引的,但是在虚拟生成的列上创建的二级
  索引不支持ICP;
5.引用子查询的条件不能下推;
6.引用存储功能的条件不能被下推,存储引擎不能调用存储功能;
7.触发条件不能被下推。

5.要想了解了解ICP的工作原理,首先需要了解不适用ICP时索引扫描的方式

1.获取下一行数据,首先通过读取索引图,然后使用索引图来定位和读取完整的一行
  数据;
2.检验适用于此表的【where】条件部分,根据检验结果接受或拒绝一行数据。

6. 使用ICP时索引的扫描方式

1.获取下一行的索引图(但不是完整的表行);
2.检验适用于此表的【where】条件部分,并且只检查索引列,如果条件
  不满足,则转到下一行的索引图;
3.如果条件满足,则使用索引图来定位和读取整个表行的数据;
4.检测此表【where】条件的剩余部分,基于检测结果,接受或者拒绝一行数据。

7. 举例:

假设一张表【people】,包含了人员和他们的地址信息。并且该表定义了一个【INDEX】索引(邮编,姓氏,名字)。如果我们知道了一个人的邮编,但是不确定这个人的姓氏,我们可以进行如下检索:

SELECT * FROM people
  WHERE zipcode='95054'
  AND lastname LIKE '%etrunia%'
  AND address LIKE '%Main Street%';

解析该sql:

 1. MySQL可以使用索引扫描zipcode='95054'的表数据;
 2. 第二部分(lastname LIKE
    '%etrunia%')不能用于限制必须扫描的行数;因此如果没有ICP,这个查询必须检索所有符合zipcode='95054'的数据。
 3. 如果开启ICP,存储引擎在返回数据之前会先校验lastname LIKE '%etrunia%'的条件,
 4. 这避免了返回符合zipcode但不符合lastname条件的数据。

ICP在默认的情况下是开启的,可以通过optimizer_switch参数来控制ICP的开启与关闭:

SET optimizer_switch = 'index_condition_pushdown=off';
SET optimizer_switch = 'index_condition_pushdown=on';

你可能感兴趣的:(mysql,索引)