连接的本质就是把各个连接表中的记录都取出来依次匹配的组合加入结果集并返回给用户
连接过程
- 首先确定第一个需要查询的表,这个表称之为 驱动表 ;根据单表查询条件查询
- 针对 驱动表 产生的结果集中的每一条记录,分别需要到 被驱动表 表中查找匹配的记录
内连接和外连接
- 内连接的两个表,驱动表中的记录在被驱动表中找不到匹配的记录,该记录不会加入到最后的结果集,我们上边提到的连接都是所谓的内连接
- 对于外连接的两个表,驱动表中的记录即使在被驱动表中没有匹配的记录,也仍然需要加入到结果集
- 左外连接:选取左边的表为驱动表
- 右外连接:选取右边的表为驱动表
涉及 单表 的过滤条件放到 WHERE 子句中,把涉及 两表 的过滤条件都放到 ON 子句中,我们也一般把放到 ON子句中的过滤条件也称之为连接条件
连接的原理
嵌套循环连接(Nested-Loop Join)
驱动表只访问一次,但被驱动表却可能被多次访问,访问次数取决于对驱动表执行单表查询后的结果集中的记录条数的连接执行方式称之为嵌套循环连接(Nested-Loop Join)
- 在连接查询中对被驱动表使用主键值或者唯一二级索引列的值进行等值查找的查询执行方式称之为:eq_ref
- 连接查询的查询列表和过滤条件中可能只涉及被驱动表的部分列,而这些列都是某个索引的一部分,这种情况下即使不能使用eq_ref、ref、ref_or_null或者range这些访问方法执行对被驱动表的查询的话,也可以使用索引扫描
基于块的嵌套循环连接(Block Nested-Loop Join)
MySQL中这种加入了join buffer的嵌套循环连接算法称之为基于块的嵌套连接(Block Nested-Loop Join)算法,join buffer就是执行连接查询前申请的一块固定大小的内存,先把若干条驱动表结果集中的记录装在这个join buffer中,然后开始扫描被驱动表,每一条被驱动表的记录一次性和join buffer中的多条驱动表记录做匹配,因为匹配的过程都是在内存中完成的,所以这样可以显著减少被驱动表的I/O代价
