- 索引条件下推(Index Condition Pushdown)是 MySQL 5.6 版本的新特性,是一种对多列索引的最左匹配原则条件下对索引利用的完善优化。
- 索引条件下推把本来由 Server 层做的索引条件检查向下推给存储引擎层处理,以降低回表和访问存储引擎的次数,提高查询效率。
- 如果索引中包含 WHERE 子句中的所有条件,就可以使用索引条件下推来优化查询。它会将 WHERE 子句中的条件下推到存储引擎层处理,减少数据读取的行数,从而提高查询效率。
- 假设有多列索引(name, age),需要检索出表中姓名第一个字是张,而且年龄是10岁的所有用户
示例
SELECT * FROM user
WHERE name LIKE '张%' AND age=10;
- 在没有索引条件下推之前,会根据非聚簇索引先找到所有姓名第一个字是张字段所对应的主键 id
- 然后根据主键 id 回表查询出所有数据行,再根据返回的数据行的 age 再筛选一次,因此这A个过程需要执行多次回表查询。而且根据最左匹配原则,只能匹配 name 索引列,没有利用到 age 的索引列,因索引失效,执行全表扫描
- 开启索引条件下推后,存储引擎会直接在多列索引中对 age 索引列进行处理,按照 age=10 过滤,然后再执行回表查询返回数据行,索引生效,执行全索引扫描
- 索引条件下推的思路是充分利用索引列,尽量在查询出整行数据之前过滤无效的数据,减少回表的次数,大提升查询的效率
注
- 索引条件下推只能用于 range、 ref、 eq_ref、ref_or_null 访问模式。索引条件下推对于联合索引的部分列模糊查找非常有效
- 索引条件下推只能用于InnoDB和 MyISAM存储引擎及其分区表(5.6版本不适用分区表查询,5.7版本后可以用于分区表查询)
- 对InnoDB存储引擎,索引条件下推只适用于非聚簇索引。聚簇索引通过一次查询就能取出数据,不需要使用索引下推
- 索引条件下推不支持基于虚拟列上建立的索引,比如函数索引
- 索引条件下推不支持引用子查询的条件
索引下推的开启和关闭
- 可以通过设置 optimizer_switch 系统变量,控制索引下推的关闭和开启,默认情况下索引下推开启
示例
SET optimizer_switch='index_condition_pushdown=off';
SET optimizer_switch='index_condition_pushdown=on';