1.普通条件下推
举个例子:区间合并
SELECT name,age FROM user_info WHERE id>10 AND id>5;
会被优化成:
SELECT name,age FROM user_info WHERE id>10;
再举个例子:HAVING to WHERE
SELECT t1.a,MAX(t1.b)
FROM t1
GROUP BY t1.a
HAVING (t1.a>2) AND (MAX(t1.c)>12);
会被优化成:
SELECT t1.a,MAX(t1.b)
FROM t1
WHERE (t1.a>2)
GROUP BY t1.a
HAVING (MAX(t1.c)>12);
2.索引条件下推
WHY: DBMS 优化器根据成本决定访问方法。如果开发者理解索引条件下推的原理,就可以主动引导优化器选择走索引的访问方法(当然了,走索引快还是不走索引快,得经过实测)。
2.1索引条件下推概念
Index Condition Pushdown(ICP) 是 MySQL 5.6 中新特性,是一种在存储引擎层使用联合索引过滤数据的一种优化方式,可以减少在存储引擎层回表的次数,减少返回给 server 层的数据量。
如果没有用到索引条件下推,sql 执行的过程是:
-
以联合索引中的某个列作为过滤条件,在联合索引树中找到符合条件的记录。
-
根据符合条件的记录中的主键值进行回表。
-
将回表得到的完整记录返回给 server 层,并在 server 层按其他条件做进一步过滤。
用到了索引条件下推,sql 执行的过程是:
- 以联合索引中的多个列(如果都在联合索引中)作为过滤条件,在联合索引树中找到符合条件的记录。
- 根据符合条件的记录中的主键值进行回表。
- 将回表得到的完整记录返回给 server 层,并在 server 层按其他条件做进一步过滤。
我们可以发现,ICP 通过用联合索引中的多个列作为过滤条件,减少了需要回表的记录数,减少了返回给 server 层的记录数,从而优化了查询效率。
2.2索引条件下推使用条件
- 只能用于
range
、ref
、eq_ref
、ref_or_null
访问方法; - 只能用于
InnoDB
和MyISAM
存储引擎及其分区表(5.7版本的开始支持); - 对
InnoDB
存储引擎来说,索引下推只适用于二级索引;
参考: 五分钟搞懂MySQL索引下推