Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化( 二 )


三丶索引合并通常情况下 , mysql只会为单个索引生成扫描区间 , 但是存在特殊情况 , mysql可以为多个索引生成扫描区间 , 这种多个索引生成扫描区间来完成依次查询的方法称为索引合并
1.交集索引合并select xxx ,xxx from table where key1=1 and key2=2 (key1和key2都是二级索引)mysql可以选择使用key1 , 也可以使用key2索引 , 获取符合的主键然后回表并过滤不符合的记录 。也可以分别从key1索引中获取满足key1=1 , 从key2索引中获取 key2=2的主键值 , 再获取二者交集最后进行回表 , 这样可与减少不必要的回表操作 。
使用交集索引合并的话 , 要求通过二级索引查到的主键本身就是有序的 , 这样获取交集效率更高 , 并且减少了随机IO 。

  • 如果具有a,b两个普通索引,执行查询select * from table where a>1 and b=2 那么是无法进行交集索引合并的,因为a>1得到的主键并不是有序的 , 
  • 同样联合索引q,w,e 普通索引r 执行select * from table where q=1 and w=2 and r=3也不可以使用交集索引合并 , 因为联合索引是依次根据q,w,e排序的 , 满足q=1 and w=2的数据主键并不是有序的 。
  • 普通索引a , 主键为id , select * from a=1 and id>100这样的查询理论上是主键有序可与使用的 , 但是mysql会找到满足a=1且id>100的第一条记录 , 然后向右直到不符合条件的数据出现 , 这种情况也不需要使用交集索引合并
2.并集索引合并【Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化】select * from table where a>1 or b>2 a,b均为普通索引 , 无法只使用a或者b索引进行查询 , 但是可分别从a和b中获取满足条件的主键 , 然后取二者并集后回表即可 。这称之为并集索引合并 , 同样也是要求从单个索引获取到的主键值是有序的 , 
3.排序并集索引合并并集索引合并要求根据单个索引获取到的主键是有序的 , 然后取并集回表 , 条件比较苛刻 。mysql支持分别从各个索引中扫描得到记录的主键让排序 , 再取并集进行回标查询 , 这种称为排序并集索引合并
四丶连表查询的原理上面我们研究了单表查询 , 下面我们学习一下多表连接查询
1.连接的本质连接的本质就是将各个表中的数据都取出来进行依次匹配 , 并且将匹配后的结果发送回客户端 。无论那个表作为驱动表产生的笛卡尔积肯定是一样的 , 而对于内连接来说凡是不符合on和where的查询都不会加入到结果集 , 内连接的驱动表和被驱动表可以交换 , 但是对于外连接来说 , 驱动表中的记录即使在被驱动表中找不到符合on的记录 , 也会被加入到结果集 , 驱动表和被驱动表不可随意交换
Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化

文章插图
2.连接中的过滤条件在连接时过滤掉特定的记录是非常必要的(如果不进行过滤那么就是多表的笛卡尔积 , 条数是多个表条数的乘积)多表连接查询中的过滤条件分为一下两种