外部結合には、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
条件に一致する行がない場合、すべてのカラムがNULL
に設定された追加のB
行が生成されます。LEFT JOIN
を使用して、一部のテーブルに存在しない行を検索し、WHERE
部分の
のテストを実行した場合 (ここでcol_name
IS NULLcol_name
はNOT NULL
と宣言されているカラム)、MySQL はLEFT JOIN
条件に一致する 1 つの行が見つかったあとに、それ以上の行 (の特定のキーの組み合わせ) の検索を停止します。
RIGHT JOIN
の実装は、テーブルロールを逆にした LEFT JOIN
の実装に似ています。 セクション8.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;
MySQL 8.0.14 以降では、定数リテラル式から発生する簡単な 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
これによりクエリー計画が改善される場合、オプティマイザはテーブル t1
の前にテーブル t2
を使用できるようになりました。 テーブルの結合順序に関するヒントを提供するには、オプティマイザヒントを使用します。セクション8.9.3「オプティマイザヒント」 を参照してください。 または、STRAIGHT_JOIN
を使用します。セクション13.2.10「SELECT ステートメント」 を参照してください。 ただし、STRAIGHT_JOIN
では準結合変換が無効になるため、インデックスの使用が妨げられる場合があります。セクション8.2.2.1「準結合変換による IN および EXISTS サブクエリー述語の最適化」 を参照してください。