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的話,需要讓小表做驅動表,這樣才能有效減少循環次數。但是需要注意的是,這個結論的前提是可以使用被驅動表的索引。