那么是无法进行交集索引合并的,因为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
的数据主键并不是有序的 。select * from a=1 and id>100
这样的查询理论上是主键有序可与使用的,但是mysql会找到满足a=1且id>100的第一条记录,然后向右直到不符合条件的数据出现,这种情况也不需要使用交集索引合并select * from table where a>1 or b>2
a,b均为普通索引,无法只使用a或者b索引进行查询,但是可分别从a和b中获取满足条件的主键,然后取二者并集后回表即可 。这称之为并集索引合并,同样也是要求从单个索引获取到的主键值是有序的,3.排序并集索引合并并集索引合并要求根据单个索引获取到的主键是有序的,然后取并集回表 , 条件比较苛刻 。mysql支持分别从各个索引中扫描得到记录的主键让排序 , 再取并集进行回标查询,这种称为排序并集索引合并
四丶连表查询的原理上面我们研究了单表查询,下面我们学习一下多表连接查询
1.连接的本质连接的本质就是将各个表中的数据都取出来进行依次匹配,并且将匹配后的结果发送回客户端 。无论那个表作为驱动表产生的笛卡尔积肯定是一样的,而对于内连接来说凡是不符合on和where的查询都不会加入到结果集,内连接的驱动表和被驱动表可以交换,但是对于外连接来说,驱动表中的记录即使在被驱动表中找不到符合on的记录,也会被加入到结果集,驱动表和被驱动表不可随意交换
文章插图
2.连接中的过滤条件在连接时过滤掉特定的记录是非常必要的(如果不进行过滤那么就是多表的笛卡尔积,条数是多个表条数的乘积)多表连接查询中的过滤条件分为一下两种
- 单表查询的搜索条件
比如select * from a left join b where a>1
,这里的单表查询搜索条件就是a>1
,如果a
是索引那么将使用单表查询的range
访问方法
- 涉及两表的条件
比如select * from a , b where a.k1 = b.k2 and a.k3>b.k4
,这里涉及的条件便是a.k1 = b.k2 and a.k3>b.k4
,对于这种擦好像执行过程如下
- 首先确定第一个需要查询的表,称为驱动表
mysql会选择代价最小的访问方法对驱动表进行查询
1
中的驱动表获取到的每一条记录,都需要去另外一张表中查询匹配的记录
比如在a作为驱动表获取到了a.k1=1,a.k3=2
那么接下来需要去表b中查询满足1=b.k2 and 2>b.k4
的记录(并不是将在驱动表中获取到的记录缓存起来,再一起到被驱动表中进行查询,而是每在驱动表中获取到一条记录都会到被驱动表中查询满足的数据)
- 首先确定第一个需要查询的表,称为驱动表
- 对于内连接的两个表,如果驱动表中的记录在被驱动表中找不到匹配的记录,那么该记录不会加入到最后的结果集 。
如select * from user_detail d ,user u where u.id = d.id
查询结果如下
文章插图
user_detail
中具备非常多的记录,但是和user
中id匹配的记录只有id=3,这里也只能查出一条记录
- 对于外连接的表,即使驱动表中的记录在被驱动表中找不到匹配的记录,那么也会加入到结果集中
如select * from user_detail d left join user u onu.id = d.id
查询结果如下
文章插图
即使在onu.id = d.id
的限制下,只有id=3满足,其他id不满足 , 也会将其他记录加入到结果集,被驱动的字段使用null填充
左外连接 即左连接
,右外连接 即右连接
,二者的区别在于左连接
是左边的表作为驱动表,右连接
使用右边的表作为驱动表 。5.where 和 on在外连接中存在
where
和 on
两种过滤条件 。- where
无论是内连接,还是外连接,只要不符合where条件的记录都不会加入到最后的结果集中
- 手机怎样连接我的电脑(手机怎么访问自己电脑)
- MYSQL-->InnoDB引擎底层原理
- 浅谈MySQL、Hadoop、BigTable、Clickhouse数据读写机制
- Docker | Compose创建mysql容器
- 一文读懂 MySQL 索引
- 如何优雅的备份MySQL数据?看这篇文章就够了
- 【博学谷学习记录】超强总结,用心分享|MySql连接查询超详细总结
- day08-MySQL事务
- MySQL 窗口函数
- 线上服务宕机,码农试用期被毕业,原因竟是给MySQL加个字段