8.MySQL8.0索引条件下推优化(ICP)

介绍

索引条件下推(ICP)是对MySQL使用索引从表中检索行的情况的优化。 如果没有ICP,存储引擎会遍历索引以查找基表中的行,并将它们返回给MySQL服务器,该服务器会评估行的WHERE条件。 启用ICP后,如果只使用索引中的列来评估WHERE条件的某些部分,MySQL服务器会将WHERE条件的这一部分推送到存储引擎。 然后,存储引擎通过使用索引条目来评估推送的索引条件,并且仅当满足该条件时才从表中读取行。 ICP可以减少存储引擎必须访问基表的次数以及MySQL服务器必须访问存储引擎的次数。

讲解

Index Condition Pushdown适用于以下情况:

  • 当进行全表访问时,ICP用于range,ref,eq_ref和ref_or_null访问方法。
  • ICP可用于InnoDB和MyISAM表,包括分区的InnoDB和MyISAM表。
  • 对于InnoDB表,ICP仅用于二级索引。 ICP的目标是减少全行读取的数量,从而减少I/O操作。 对于InnoDB聚簇索引,完整记录已经读入InnoDB缓冲区。 在这种情况下使用ICP不会降低I/O.
  • 在虚拟生成列上创建的二级索引不支持ICP。 InnoDB支持虚拟生成列的二级索引。
  • 引用子查询的条件无法下推。
  • 引用存储过程的条件无法下推。 存储引擎无法调用存储过程。
  • 触发器也无法执行此优化。

下面解释一下不使用ICP技术时,索引扫描方式:

  • 获取下一行,首先读取索引元组,然后使用索引元组找到并读取整个表行。
  • 然后根据Where条件判断这行是否满足条件,根据结果判断是否保留该行

在使用索引条件下推之后,索引扫描方式改为如下模式:

  • 获取下一行的索引元组(但不是完整的表行)。
  • 测试适用于此表的WHERE条件的一部分,并且只能使用索引列进行检查。 如果不满足条件,则继续下一行的索引元组。
  • 如果满足条件,请使用索引元组来查找并读取整个表行。
  • 测试Where条件的其他部分,根据结果判断是否保留该行。

EXPLAIN输出显示使用索引条件下推时在Extra列中使用索引条件。 它不显示使用索引,因为在必须读取完整的表行时不适用。

例如:

假设一个表包含有关人员及其地址的信息,并且该表的索引定义为INDEX(zipcode,lastname,firstname)。 如果我们知道一个人的邮政编码值但不确定姓氏,我们可以像这样搜索:

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

MySQL可以使用索引来扫描zipcode =‘95054’的人。 第二部分(姓氏LIKE’%etrunia%’)不能用于限制必须扫描的行数,因此如果没有Index Condition Pushdown,此查询必须为所有拥有zipcode ='95054’的人检索完整的表行。

当使用ICP时,MySQL在读取整个表行之前先检索lastname LIKE ‘%etrunia%’,它使用索引避免了读取满足zipcode='95054’的条件但是不满足lastname LIKE '%etrunia%'的条件的表行。

此功能在MySQL8.0中默认开启,如需关闭使用如下语句

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

猜你喜欢

转载自blog.csdn.net/ciqingloveless/article/details/83583756