
连接的本质是将每个表的数据都取出来,进行相互的匹配,从而形成一个结果集返回给用户(迪卡尔积)
连接有分为
- 内连接(inner join / cross join)
- 左连接(left join) : 选取左侧的表为驱动表
- 右连接(right join): 选取右侧的表为驱动表
tips : 我们在使用join查询的时候经常会用到where与on这两个关键字
where : 不论是内连接还是外连接,凡是不符合WHERE子句中的过滤条件的记录都不会被加入最后的结果集
on : 对于外连接的驱动表的记录来说,如果无法在被驱动表中找到匹配ON子句中的过滤条件的记录,那么该记录仍然会被加入到结果集中,对应的被驱动表记录的各个字段使用NULL值填充 (可以理解成on是专门应对外连接使用的)
原理
嵌套循环连接(Nested-Loop Join)
使用join关联的查询一般步骤为:
(1)step1 : 选择驱动表,使用驱动表相关的过滤条件,选择单表查询代价最低的方式进行单表查询
(2)step2 : 对驱动表中查询得到的结果再依次匹配被驱动表,获取结果

整个过程就类似一层一层的嵌套查询一般,因此我想也是为什么阿里手册上明确禁止3张表以上的关联查询。
很明显,我们可以使用增加数据索引的方式,来增加对被驱动表的查询效率
举个例子:
SELECT * FROM t1, t2 WHERE t1.m1 > 1
AND t1.m1 = t2.m2
AND t2.n2 < 'd';
假设驱动表查询的结果有两个数据,分别为 t1.m1 = 1, t1.m1 = 2
那么对被驱动表的查询就变成了:
SELECT * FROM t2 WHERE t2.m1 = 1 and t2.n2 < d;
SELECT * FROM t2 WHERE t2.m1 = 2 and t2.n2 < d;
显然,我们可以对t2表的m1建立二级索引,那么其查询的级别是ref,需要再一次回表查询 t2.n2 < d的情况。
如果我们对n2建立索引的话,那么其查询的级别是range
如果t2表中的m1是主键或者唯一索引,那么其查询的级别是const
以上是join原理的一个总结,我平常在工作中也会经常碰到一个join的查询需求,我们不一定是谈join就色变。我们要学会使用 explain 分析特定的语句进行取舍。