MySQL の
は以下のように実装されます。
A
B
join_condition
テーブルB
はテーブル
A
と
A
が依存するすべてのテーブルに依存するように設定される。
テーブル A
は、LEFT
JOIN
条件で使用されるすべてのテーブル(B
を除く)に依存するように設定される。
LEFT JOIN
条件は、テーブル
B
からのレコードの取り出し方法の判定に使用される。(言い換えると、WHERE
節の条件はいずれも使用されない)。
あるテーブルが全てのテーブルの後に読み取られる場合を除き、通常の最適化全てが行われる。依存関係が循環している場合は、MySQL からエラーが出力される。
標準の
WHERE
最適化すべてが実行される。
A
にWHERE
節の条件にマッチするレコードがあり、B
に
ON
条件にマッチするレコードがない場合、B
のカラムの値が
NULL
に設定されたレコードが生成される。
テーブルのいずれかに存在しないレコードを検索する際に
LEFT JOIN
を使用した場合:
のcol_name
IS
NULLWHERE
節内で、NOT
NULL
と定義した
col_name
を column_name IS NULL
で評価した場合、 MySQL は LEFT
JOIN
条件に一致するレコードを 1
つ検索すると、その後はレコードの検索(特定のキー組み合わせの)を停止する。
RIGHT JOIN
の実装は LEFT
JOIN
と類似しています。
結合オプティマイザがテーブルの結合順序を計算します。テーブル読み取り順序は
LEFT JOIN
と
STRAIGHT_JOIN
によって強制されるため、チェック対象のテーブル順列が減少し、結合オプティマイザ(テーブルの結合順序を計算する)の動作の速度がさらに上がります。
LEFT JOIN
が
d
の前に読み取るように強制するため、MySQL
では
b
の完全スキャンが実行されることに注目してください。
SELECT * FROM a JOIN b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON (d.key=a.key) WHERE b.key=d.key;
この場合の修正は逆さに行われ、a
とb
がFROM
節でリストされています。
SELECT * FROM b JOIN a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON (d.key=a.key) WHERE b.key=d.key;
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;
これでクエリが改善できる場合、MySQL
がテーブル
t1
を読み取る前にテーブル
t2
を使用できるようになるためスピードが向上します。テーブルの順序を指定して強制する場合は
STRAIGHT_JOIN
を使用します。