問題の歴史:
EXISTS演算子とIN演算子は、サブクエリに基づいてレコードをフィルタリングするために使用されます。SQLの登場以来、開発者はどちらを選択するかについて悩み、どの方法が速いのか、どのような場合にその使用が好ましいかを理解しようとしてきました。
問題:
主な課題は、外部または内部のテーブルに一致する行のみを取得することです。これは、データセットが大きい場合には常にパフォーマンスにとって重要です。EXISTSとINの選択は、サブクエリの構造、返される値の数と一意性、使用するDBMSによって異なります。
解決策:
コード例:
-- INの使用 SELECT name FROM students WHERE id IN (SELECT student_id FROM enrollments WHERE course = 'SQL'); -- EXISTSの使用 SELECT name FROM students WHERE EXISTS (SELECT 1 FROM enrollments WHERE enrollments.student_id = students.id AND enrollments.course = 'SQL');
主な特徴:
INのサブクエリでNULLに出会った場合、何が起こるか?
ほとんどの人は、INが単にNULLを無視すると考えていますが、NULLが存在すると結果が予測不可能になることがあります。例えば、クエリ:
SELECT id FROM orders WHERE client_id IN (1, NULL, 2);
技術的にはclient_idが1または2でない行は含まれませんが、サブクエリのリストにNULLしか含まれない場合、結果は空になります。
EXISTSとINは完全に互換性のある構文か?
いいえ。EXISTSの使用は通常速く、サブクエリ全体を分析する必要がないためです。さらに、INは複数の列からのサブクエリでは機能しませんが、EXISTSは機能します。これは、WHEREの条件に基づいて比較が行われるからです。例えば:
SELECT col1 FROM t1 WHERE (col1, col2) IN (SELECT col3, col4 FROM t2);
この形式は多くの場合サポートされていませんが、対応するEXISTSはサポートされています。
INはインデックスされたフィールドでEXISTSよりも速く動作することがあるか?
はい、サブクエリが小さく、比較されるフィールドにインデックスがある場合、INが速くなることがあります。しかし、大規模なサンプルやインデックスがない場合は逆です。
アナリストはINを用いてレポートを作成しましたが、サブクエリが数十万行のNULLを返すことを考慮していませんでした。レポートは数分間動作し、時にデータを失いました。
利点:
同じクエリをEXISTSに書き換え、追加の条件を入れ、インデックスを再計算しました。
利点: