外連接包含 LEFT JOIN
和 RIGHT JOIN
。
MySQL 實作
如下A
LEFT JOIN B
join_specification
資料表
B
設定為依賴於資料表A
以及A
依賴的所有資料表。資料表
A
設定為依賴於LEFT JOIN
條件中使用的所有資料表(除了B
)。LEFT JOIN
條件用於決定如何從資料表B
擷取列。(換句話說,不會使用WHERE
子句中的任何條件。)執行所有標準聯結最佳化,但資料表始終會在它依賴的所有資料表之後讀取。如果存在循環依賴,則會發生錯誤。
執行所有標準
WHERE
最佳化。如果
A
中有符合WHERE
子句的列,但在B
中沒有符合ON
條件的列,則會產生一個額外的B
列,且所有欄位都設定為NULL
。如果您使用
LEFT JOIN
來尋找某些資料表中不存在的列,並且您在WHERE
部分中有以下測試:
,其中col_name
IS NULLcol_name
是一個宣告為NOT NULL
的欄位,則 MySQL 在找到符合LEFT JOIN
條件的一列後,會停止搜尋更多列(對於特定的金鑰組合)。
RIGHT JOIN
的實作方式與 LEFT JOIN
類似,只是資料表角色反轉。如第 10.2.1.10 節「外連接簡化」中所述,右連接會轉換為等效的左連接。
對於 LEFT JOIN
,如果產生的 NULL
列的 WHERE
條件始終為 false,則 LEFT JOIN
會變更為內部聯結。例如,如果 t2.column1
為 NULL
,則在以下查詢中,WHERE
子句將為 false
SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;
因此,將查詢轉換為內部聯結是安全的。
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;
由常數文字表達式產生的無意義 WHERE
條件會在準備階段移除,而不是在最佳化的後期階段,此時聯結已簡化。提前移除無意義條件可以讓最佳化工具將外部聯結轉換為內部聯結;這可以改善在 WHERE
子句中包含無意義條件的外部聯結查詢的計劃,例如這個查詢。
SELECT * FROM t1 LEFT JOIN t2 ON condition_1 WHERE condition_2 OR 0 = 1
最佳化工具現在在準備階段看到 0 = 1 永遠為 false,使得 OR 0 = 1
是多餘的,並將其移除,留下這個:
SELECT * FROM t1 LEFT JOIN t2 ON condition_1 where condition_2
現在,最佳化工具可以將查詢重寫為內部聯結,如下所示:
SELECT * FROM t1 JOIN t2 WHERE condition_1 AND condition_2
現在,如果先使用資料表 t2
會產生更好的查詢計劃,則最佳化工具可以使用資料表 t2
而不是資料表 t1
。若要提供有關資料表聯結順序的提示,請使用最佳化工具提示;請參閱第 10.9.3 節,「最佳化工具提示」。或者,使用 STRAIGHT_JOIN
;請參閱第 15.2.13 節,「SELECT 陳述式」。但是,STRAIGHT_JOIN
可能會因為它停用了半聯結轉換而無法使用索引;請參閱使用半聯結轉換最佳化 IN 和 EXISTS 子查詢述詞。