1. intersection索引合并
如果用到了多个索引(假设是两个),走索引合并的过程是指:
1.先根据索引1筛选出范围;
2.再根据索引2筛选出范围后,与1的范围做交集;
3.根据最终范围回表查询(如果需要回表的话)。
不走索引合并的过程是上面步骤的132顺序。
举例说明如下:
假设a、b字段分别建了索引,c、d字段建了一个联合索引,id字段是主键索引。
以下sql可能走索引合并:
select * from t where a=x and b=y;
select * from t where id>x and b=y;
select * from t where a=x and c=y and d=z;
以下sql不可能走intersection索引合并:
select * from t where a>x and b=y;
select * from t where a=x and c=y;
也就是说,要走intersection索引合并:
1. 如果用到了二级索引,二级索引必须是等值查询;
2. 如果用到了联合索引,必须把联合索引的每个字段都用上,且这些字段都是等值查询;
3. 如果用到主键索引,对于主键索引是没有限制。
满足以上条件,也不一定肯定会走索引合并,mysql的查询优化器还会计算走和不走哪个效率高,不走效率高,它就不走。
2. union索引合并
与intersection索引合并的差别仅仅在以下两点:
- 步骤2中是取范围的并集而不是交集;
- 其sql查询条件里是or不是and。
3. sort-union索引合并
select * from t where a>x or b<y;这种sql是不会走union索引合并的,但可能走sort-union索引合并,过程如下:
1.根据索引a查到一个范围的主键,对这些主键排序;
2.根据索引b查到一个范围的主键,对这些主键排序;
3.对步骤1和2里的主键们进行合并;
4.根据要求看是否回表。
4. 总结
mysql最终会走那种索引合并策略,是根据查询优化器计算估计后决定的,不是满足以上某种情况就一定会走对应的索引合并方式。
注意,没有sort-intersection。因为sort-union从索引获取的记录数少,即使排序,成本也不会太高。而intersection是从索引中获取的记录较多,排序成本太高。