8.2.1.6 Index Condition Pushdown Optimization 索引条件内推优化
Index Condition Pushdown (ICP) 用于在MySQL从表中使用索引检索记录。
没有ICP,存储引擎遍历索引从表中找到相应的记录,返回给MySQL server ,评估WHERE 条件。
当启动ICP的时候,如果WHERE 条件部分可以通过只使用一个列从索引,
MySQL server 将这部分where 条件内推到存储引擎,存储引擎然后通过使用index entry进行评估,
只有当它满足从表里读取记录。ICP可以降低存储引擎访问base table的次数
Index Condition Pushdown 可以用于range,ref,eq_ref和ref_or_null 访问方法,
当需要访问表的全部记录。 这个策略可以用于 InnoDB and MyISAM tables.
(注意: index condition pushdown 在MySQL 5.6中不支持分区表,这个在5.7中解决)
对于InnoDB表,然而,ICP 只能用于第2个索引。 ICP的目的是江都全表读取的次数,从而降低I/O输出。
对于 InnoDB clustered indexes, 完整的记录已经被读入到InnoDB buffer,
这种情况使用ICP 不降低I/O
让优化如何工作, 首先考虑index 如何扫描处理 当 Index Condition Pushdown没有使用;
- 获取下一行,首先通过读取索引元组,然后通过使用索引元组来查找和读取全表行。
2.测试WHERE条件的部分,应用于这个表,根据测试结果接受或拒绝该行。
当 Index Condition Pushdown被使用,:
1.获取下一行的索引元组( 不是表的全部记录)
- 测试WHERE 条件的部分,应用于表,可以使用索引列进行检查。如果条件不满足,继续处理下一行的索引元组。
3.如果记录满足, 使用index 元组来查找和阅读全部的表的记录
4.测试WHERE 条件顺下的部分应用于这个表,根据测试结果接受或拒绝该行。
当 Index Condition Pushdown is used,额外的列在EXPLAIN 输出显示使用index条件,
它不会显示索引 只因为不适用于当全表必须被读取
假设我们有一个表包含信息关于people和它们的地址,表有一个索引定位 INDEX (zipcode, lastname, firstname).
如果我们知道person的zipcode值 但是不确认关于lastname,我们可以这样搜索:
SELECT * FROM people
WHERE zipcode=’95054’
AND lastname LIKE ‘%etrunia%’
AND address LIKE ‘%Main Street%’;
MySQL 可以使用index 来扫描people使用zipcode=’95054’,
第2部分 (lastname LIKE ‘%etrunia%’) 不能用于限制记录数但是必须被扫描,
因此没有 Index Condition Pushdown,这个查询必须检索 zipcode=’95054’.所有的记录。
Index Condition Pushdown,MySQL 会检查lastname LIKE ‘%etrunia%’部分 在读取整个表之前,
这个避免读取整个记录对应的所有Index tuples,不匹配lastname条件的。
Index Condition Pushdown