第11章 表连接的原理
前导知识
连接:将各个表中的记录都取出来进行依次匹配,将匹配后的结果发给客户端
笛卡尔积:连接查询的结果中包含一个表的每一条记录与另一个表中每一条记录的组合,这样的查询结果就是笛卡尔积
比如表a有5条记录;表b有6条记录;a和b的笛卡尔积就是30
连接过程
1、确定第一个需要查询的表,此表为驱动表
2、从驱动表中取每一条符合搜索条件的记录,到接下来的表中查找匹配的记录;驱动表之后的那个表就叫被驱动表
只需要访问驱动表一次,可能会多次访问被驱动表
每获得一条满足条件的驱动表记录,马上到被驱动表中寻找匹配的记录
内/外连接
内连接
-
what:驱动表中的记录在被驱动表中找不到匹配的记录,那么驱动表的这条记录不会加入到最后的结果中
-
select * from 驱动表, 被驱动表; select * from 驱动表 join 被驱动表; select * from 驱动表 inner join 被驱动表; select * from 驱动表 cross join 被驱动表;
-
外连接
-
what:驱动表中的记录在被驱动表中找不到匹配的记录,也仍需要加入到最后结果中
-
左外连接:语句左侧的表为驱动表
-
select * from 驱动表 left join 被驱动表 on 连接条件;
-
-
右外连接:语句右侧的表为驱动表
-
select * from 被驱动表 right join 驱动表 on 连接条件;
-
对于内连接,驱动表和被驱动表的顺序可以更换;对于外连接,这个顺序不能随意更换
过滤条件
- where:不论内外连接,只要是不符合where子句的记录都不会加入到最后的结果中
- on:在内连接中与where等价;
在外连接中,如果驱动表中的记录在被驱动表中没有记录可以匹配,该驱动表记录仍会加入到结果中,对应的被驱动表字段以null填充
嵌套循环连接
what:如果有3个表进行连接,那么表1和表2完成连接后的结果作为驱动表,将表3作为被驱动表进行连接查询
使用索引加快连接速度
why:在根据驱动表的一条记录去被驱动表中查询时,相当于确定搜索条件的单表查询,可以使用索引优化单表查询
在被驱动表上使用二级索引进行查询时,可能连接查询的变量和过滤条件都是二级索引的部分列,可以不用回表直接覆盖索引,所以最好不要用*作为查询列表,而是使用真正需要查询的列
基于块的嵌套循环连接
why:减少被驱动表的访问次数
Join Buffer连接缓冲区:在执行连接查询前申请一块固定大小的内存,先把若干条驱动表结果集中的记录放在buffer中;在扫描被驱动表时,每一条被驱动表的记录与buffer中的多条驱动表记录进行匹配