標籤:
基礎概念:
內外連接的區別是內連接將去除所有不合格記錄,而外連接則保留其中部分。外左連接與外右連接的區別在於如果用A左連接B則A中所有記錄都會保留在結果中,此時B中只有符合連接條件的記錄,而右連接相反,這樣也就不會混淆了。
差集:
select table1.* from table1 left join table2 using(id) where table2.id is null
交集:
select table1.* from table1 left join table2 using(id)
效能:
1:顯示(explicit) inner join VS 隱式(implicit) inner join
select * from table a inner join table b on a.id = b.id;
VS
select a.*, b.* from table a, table b where a.id = b.id;
我在資料庫中比較(10w資料)得之,它們用時幾乎相同,第一個是顯示的inner join,後一個是隱式的inner join。
2:left join/right join VS inner join 盡量用inner join.避免 LEFT JOIN 和 NULL.
3:on與 where的執行順序:
ON 條件(“A LEFT JOIN B ON 條件運算式”中的ON)用來決定如何從 B 表中檢索資料行。如果 B 表中沒有任何一行資料匹配 ON 的條件,將會額外產生一行所有列為 NULL 的資料,在匹配階段 WHERE 子句的條件都不會被使用。僅在匹配階段完成以後,WHERE 子句條件才會被使用。ON將從匹配階段產生的資料中檢索過濾。
所以我們要注意:在使用Left (right) join的時候,一定要在先給出儘可能多的匹配滿足條件,減少Where的執行。如:
PASS
代碼如下:
select * from A
inner join B on B.name = A.name
left join C on C.name = B.name
left join D on D.id = C.id
where C.status>1 and D.status=1;
Great
代碼如下:
select * from A
inner join B on B.name = A.name
left join C on C.name = B.name and C.status>1
left join D on D.id = C.id and D.status=1
從上面例子可以看出,儘可能滿足ON的條件,而少用Where的條件。從執行效能來看第二個顯然更加省時。
4:注意ON 子句和 WHERE 子句的不同
代碼如下:
SELECT * FROM product LEFT JOIN product_details
ON (product.id = product_details.id)
AND product_details.id=2;
SELECT * FROM product LEFT JOIN product_details
ON (product.id = product_details.id)
WHERE product_details.id=2;
第一條查詢使用 ON 條件決定了從 LEFT JOIN的 product_details表中檢索符合的所有資料行。第二條查詢做了簡單的LEFT JOIN,然後使用 WHERE 子句從 LEFT JOIN的資料中過濾掉不合格資料行。
5: 盡量避免子查詢,而用join
往往效能這玩意兒,更多時候體現在資料量比較大的時候,此時,我們應該避免複雜的子查詢。如下:
PASS
insert into t1(a1) select b1 from t2 where not exists(select 1 from t1 where t1.id = t2.r_id);
Great
insert into t1(a1)
select b1 from t2
left join (select distinct t1.id from t1 ) t1 on t1.id = t2.r_id
where t1.id is null;
mysql JOIN要點