select A.*,B.gender from A left join B on A.id=B.uid id name age gender 1 A 18 F 2 B 19 M 3 C 20 null 2 连接关键字 连接两个表我们可以用两个关键字:on,using。on可以指定具体条件,using则指定相同名字和数据类型的列作为等值判断的条件,多个则通过逗号隔开。 如下:
on: select * from A join B on A.id=B.id and B.name='' using: select * from A join B using(id,name) = select * from A join B on A.id=B.id and A.name=B.name 3 连接类型 3.1 内连接 内连接和交叉连接 语法:A join | inner join | cross join B 表现:A和B满足连接条件记录的交集,如果没有连接条件,则是A和B的笛卡尔积 特点:在MySQL中,cross join ,inner join和join所实现的功能是一样的。因此在MySQL的官方文档中,指明了三者是等价的关系。 隐式连接 语法:from A,B,C 表现:相当于无法使用on和using的join 特点:逗号是隐式连接运算符。 隐式连接是SQL92中的标准内容,而在SQL99中显式连接才是标准,虽然很多人还在用隐私连接,但是它已经从标准中被移除。从使用的角度来说,还是推荐使用显示连接,这样可以更清楚的显示出多个表之间的连接关系和连接依赖的属性。 3.2 外连接 左外连接 语法:A left join B 表现:左表的数据全部保留,右表满足连接条件的记录展示,不满足的条件的记录则全是null 右外连接 语法:A right join B 表现:右表的数据全部保留,左表满足连接条件的记录展示,不满足的条件的记录则全是null 全外连接 MySQL不支持全外连接,只支持左外连接和右外连接。如果要获取全连接的数据,要可以通过合并左右外连接的数据获取到,如 select * from A left join B on A.name = B.name union select * from A right join B on B.name = B.name;。
这里union会自动去重,这样取到的就是全外连接的数据了。
3.3 自然连接 语法:A natural join B ==== A natural left join B ==== A natural right join B 表现:相当于不能指定连接条件的连接,MySQL会使用左右表内相同名字和类型的字段作为连接条件。 特点:自然连接也分自然内连接,左外连接,右外连接,其表现和上面提到的一致,只是连接条件由MySQL自动判定。 4 执行顺序 在连接过程中,MySQL各关键字执行的顺序如下:
from -> on|using -> where -> group by -> having -> select -> order by -> limit 可以看到,连接的条件是先于where的,也就是先连接获得结果集后,才对结果集进行where筛选,所以在使用join的时候,我们要尽可能提供连接的条件,而少用where的条件,这样才能提高查询性能。
5.3 Index Nested Loop Join(INLJ) INLJ是MySQL判断能使用到被驱动表的索引的情况下采用的算法。假设A表的数据行为10,B表的数据行为100,且B.tid建立了索引,则对于select * from A left join B on A.id=B.tid,MySQL会采用Index Nested Loop Join。其过程如下:
for (a in A) { if (a.id in B.tid.Index) { output <a, tid.Index所在行>; } } 总共需要循环10次A,每次循环的时候通过索引查询一次B的数据。而如果我们反过来是B left join A的话,总共要循环100次B,由此可见如果使用join的话,需要让小表做驱动表,这样才能有效减少循环次数。但是需要注意的是,这个结论的前提是可以使用被驱动表的索引。