更新:
私のブログのこの記事は、私の回答と別の回答に対する私のコメントの両方を要約し、実際の実行計画を示しています。
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
これらのクエリは同等ではありません。テーブルが b の場合、異なる結果が得られる可能性があります キーは保存されません (つまり、b.d の値) 一意ではありません)。
最初のクエリに相当するものは次のとおりです:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
b.d の場合 UNIQUEです そのようにマークされています (UNIQUE INDEX を使用) または UNIQUE CONSTRAINT SQL Server であるため、これらのクエリは同一であり、おそらく同一のプランを使用します。
SQL Server このクエリを実行するには、次のいずれかの方法を使用できます:
- <リ>
a.c に索引がある場合 、 d UNIQUEです と b a に比べて比較的小さい 、次に条件がサブクエリとプレーンな INNER JOIN に伝播されます が使用されます (with b 先頭)
b.d にインデックスがある場合 と d UNIQUE ではありません の場合、条件も伝播され、LEFT SEMI JOIN 使用されている。上記の条件にも使用できます。
両方の b.d にインデックスがある場合 と a.c それらが大きい場合、MERGE SEMI JOIN 使用されています
どのテーブルにもインデックスがない場合、b にハッシュ テーブルが作成されます。 および HASH SEMI JOIN
どちらでもない これらのメソッドのうち、サブクエリ全体を毎回再評価します。
この仕組みの詳細については、私のブログのこのエントリを参照してください:
すべての RDBMS へのリンクがあります