背景
查询时where后面可能会涉及到多个字段,它们之间进行AND或OR。在MySQL 5.0之前,一个表一次只能使用一个索引,无法同时使用多个索引分别进行条件扫描。从5.1开始引入了index merge
技术。index merge
技术就是对多个索引分别进行条件扫描,然后将他们各自的结果进行合并
该特性主要会体现在以下场景:
- 对OR语句求并集
- 对AND语句求交集
- 对AND和OR组合语句求结果
在满足index merge条件下的查询计划中会出现type:index_merge
。
AND取交集(union)
union就是多个索引条件扫描,对得到的结果进行并集运算,显然是多个条件之间进行的是 OR 运算。
案例:SELECT * FROM tmp_index_merge where key1_part1 = 2 and key2_part1 = 4\G
OR取并集(intersect)
intersect就是多个索引条件扫描得到的结果进行交集运算。
案例:SELECT * FROM tmp_index_merge where key1_part1 = 2 or key2_part1 = 4\G
AND和OR组合取并集(sort_union)
多个条件扫描进行 OR 运算,但是不符合 index union merge算法的,此时可能会使用 sort_union算法。1
2SELECT * FROM tbl_name WHERE key_col1 < 10 OR key_col2 < 20;
SELECT * FROM tbl_name WHERE (key_col1 > 10 OR key_col2 = 20) AND nonkey_col=30;
注意
在MySQL5.6.7之前的版本中,存在range优先原则。只要可以使用Range访问方式,那就不会再使用index merge。
总结
索引合并机制并不是什么新鲜东西,但是仍然存在很多人认为一条查询只能使用一个索引的观念。本篇文章只是简单的介绍MySQL存在这么一个机制,并未过深的研究。
简言之,索引合并会同时利用多个索引进行查询,尽可能得过滤掉不需要的数据行,然后再进行一次统一的回表行为。较少无谓的回表行为。
http://dev.mysql.com/doc/refman/5.6/en/index-merge-optimization.html
https://www.orczhou.com/index.php/2013/01/mysql-source-code-query-optimization-index-merge/
http://www.cnblogs.com/nocode/archive/2013/01/28/2880654.html