玩命加载中 . . .

11-连接的原理


11.1.2 连接过程简介

SELECT * FROM t1, t2 WHERE t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < 'd'

连接查询的执行过程大致如下:

  • 首先确定第一个需要查询的表,称为驱动表
  • 从驱动表中每获取到一条记录,都需要到t2表中查找匹配的记录,t2表称为被驱动表

11.1.3 内连接和外连接

针对驱动表中的某条记录,即使在被驱动表中没有匹配的记录,也仍然需要加入到结果集。为了解决这个问题,就有了内连接外连接的概念

  • 对于内连接的两个表,驱动表中的记录在被驱动表中找不到匹配的记录,该记录不会加入到最后的结果集
  • 对于外连接的两个表,驱动表中的记录即使在被驱动表中没有匹配的记录,也仍然需要加入到结果集

根据选取驱动表的不同,外连接可以细分为2种:

  • 左外连接:选取左侧的表为驱动表
  • 右外连接:选取右侧的表为驱动表

WHEREON的区别

  • WHERE子句中的过滤条件

不论是内连接还是外连接,凡是不符合WHERE子句中的过滤条件的记录都不会被加入最后的结果集。

  • ON子句中的过滤条件

对于外连接的驱动表的记录来说,如果无法在被驱动表中找到匹配ON子句中的过滤条件的记录,那么该记录仍然会被加入到结果集中,对应的被驱动表记录的各个字段使用NULL值填充。

需要注意的是,这个ON子句是专门为外连接驱动表中的记录在被驱动表找不到匹配记录时应不应该把该记录加入结果集这个场景下提出的,所以如果把ON子句放到内连接中,MySQL会把它和WHERE子句一样对待,也就是说:内连接中的WHERE子句和ON子句是等价的

1、左(外)连接的语法

SELECT * FROM t1 LEFT [OUTER] JOIN t2 ON 连接条件 [WHERE 普通过滤条件];

对于LEFT JOIN类型的连接来说,我们把放在左边的表称之为外表或者驱动表右边的表称之为内表或者被驱动表

对于左(外)连接和右(外)连接来说,必须使用ON子句来指出连接条件

2、右(外)连接的语法

LEFT换成RIGHT而已

SELECT * FROM t1 RIGHT [OUTER] JOIN t2 ON 连接条件 [WHERE 普通过滤条件];

3、内连接的语法

内连接和外连接的根本区别就是在驱动表中的记录不符合ON子句中的连接条件时不会把该记录加入到最后的结果集

由于在内连接中ON子句和WHERE子句是等价的,所以内连接中不要求强制写明ON子句

对于内连接来说,驱动表和被驱动表是可以互换的,并不会影响最后的查询结果

11.2 连接的原理

11.2.1 嵌套循环连接

驱动表只访问一次,但被驱动表却可能被多次访问,访问次数取决于对驱动表执行单表查询后的结果集中的记录条数的连接执行方式称之为嵌套循环连接

11.2.2 使用索引加快连接速度

如果访问被驱动表的方式都是全表扫描,就需要扫描很多次,所以可以给连接查询加上索引

SELECT * FROM t1, t2 WHERE t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < 'd';

这里可以考虑在t2表的m2列或者n2列上加索引

  • m2上加索引,就可以通过“t2.m2=常数值”这样的条件去获取索引记录,如果m2是主键或者唯一二级索引,代价就是常数级别的。
  • 在单表中使用主键值或者唯一二级索引列的值进行等值查找的方式称之为const
  • 连接查询中对被驱动表使用主键值或者唯一二级索引列的值进行等值查找的查询执行方式称之为eq_ref
  • n2列上建立索引,涉及到的条件是t2.n2 < 'd',可能用到range的访问方法

11.2.3 基于块的嵌套循环连接

Join Buffer就是执行连接查询前申请的一块固定大小的内存,先把若干条驱动表结果集中的记录装在这个Join Buffer中,然后开始扫描被驱动表,每一条被驱动表的记录一次性和Join Buffer中的多条驱动表记录做匹配,因为匹配的过程都是在内存中完成的,所以这样可以显著减少被驱动表的I/O代价

最好的情况是Join Buffer足够大,能容纳驱动表结果集中的所有记录,这样只需要访问一次被驱动表就可以完成连接操作了

这种加入了Join Buffer的嵌套循环连接算法称之为基于块的嵌套连接

对于优化被驱动表的查询来说,最好是为被驱动表加上效率高的索引,如果实在不能使用索引,并且自己的机器的内存也比较大可以尝试调大join_buffer_size的值来对连接查询进行优化


文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录