EXISTSとINのパフォーマンス
EXISTSが短絡評価によってINより高速になる場合を、シニア向け面接でよく出る質問として学びます。
「EXISTSとINのパフォーマンス」はCoddyKit上の無料Coding Interview Prepレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはCoding Interview Prep学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Coding Interview Prepコースには全4レッスンが含まれています。
EXISTS が実際に判定するもの
EXISTSはサブクエリを受け取り、そのサブクエリが少なくとも1行を返した瞬間にtrueになります。返される値は問題ではなく、行が存在するかどうかだけを判定します。
- これはブール値の判定であり、
WHEREで使用します。 - ほぼ常に相関しています。内部クエリが外側の行を参照するためです。
この一問は、ほぼすべての中級からシニア向けSQL面接に登場します。
基本的な EXISTS クエリ
少なくとも1件の注文を行った顧客を見つけます。内部クエリはo.customer_id = c.idによって相関しており、一致する注文が1件見つかるとすぐにEXISTSはtrueになります。
SELECT 1に注目してください — 投影される値は関係ないため、多くのエンジニアは1または*と記述します。どちらでも面接官は認めます。オプティマイザはEXISTS内部のSELECTリストを無視します。
SELECT c.name
FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id
);短絡評価
面接官が求めるキーワードは短絡評価です。EXISTSは、一致する行を1つ見つけた瞬間に内部クエリのスキャンを停止します。一致する行の完全なリストを構築したり、重複を排除したりする必要はありません。
一方、INは概念的にはサブクエリの値の集合を実体化してから、所属を確認します。内部の集合が大きい場合や重複が多い場合、この違いが重要になります。
IN を使った同じクエリ
これは、注文のある顧客を探すクエリをINで書いたものです。論理的な結果は同じですが、仕組みが異なります。サブクエリは非相関で、外側のクエリが照合する顧客IDのリストを生成します。
最近のオプティマイザでは同じ実行計画になることが多いですが、重複の多い大規模なordersでは、最初の一致で停止できるEXISTSの方が速い場合があります。
SELECT c.name
FROM customers c
WHERE c.id IN (
SELECT o.customer_id FROM orders o
);NOT EXISTS は NOT IN より優れている
これが、このレッスン全体の結論です。NOT EXISTSはアンチJOINを表現する安全な方法です。NOT INとは異なり、内部クエリのNULLによって壊れることはありません。
orders.customer_idにNULLが含まれていても、注文のないすべての顧客を確実に見つけられます。
SELECT c.name
FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id
);NOT EXISTS が NULL に安全な理由
NOT EXISTSが尋ねるのは、相関サブクエリが一致する行を見つけたかだけです — 明確なyes/noの判定です。NULLのcustomer_idはo.customer_id = c.idを満たさないため、一致することもロジック全体に影響することもありません。
NOT INでは、リスト内のNULLがUNKNOWNを引き起こし、すべての行が除外されます。これが、シニア向け面接でアンチJOINにはNOT EXISTSが好まれる理由です。
IN の方が実際に適している場合
バランスの取れた回答をしましょう — INが常に劣るわけではありません。サブクエリが小さく、静的で、重複のないリストを返す場合、INは明快で高速です:
- 数個のリテラル値、または非常に小さい参照テーブル。
- オプティマイザが一度実行してキャッシュできる非相関クエリ。
以下のクエリは完全に慣用的な書き方です。この場合にEXISTSを選ぶのは過剰設計になります。
SELECT name
FROM products
WHERE category_id IN (
SELECT id FROM categories WHERE active = true
);現代的で正直な回答
成熟したオプティマイザ(Postgres、最近のSQL ServerとMySQL)は、INとEXISTSを同じセミJOINの実行計画に書き換えることがよくあります。そのため、通常の正の所属判定ではパフォーマンスが同じになることが多いです。
それでも重要な違いは次のとおりです:
NOT INとNOT EXISTSの違い — NULLに対する正しさの問題です(単なる速度の問題ではありません)。- 非常に大きい、またはインデックスのない内部テーブル — EXISTSは短絡評価できます。
存在確認における EXISTS と JOIN
面接官が提起する別の観点は、「なぜ単にJOINしないのか」です。存在だけを確認するJOINでは、右側に重複があると行が増殖するため、DISTINCTが必要になります。EXISTSでは外側の行が重複することはありません。
したがって、純粋な存在確認では、EXISTSの方がJOIN ... DISTINCTより簡潔です。もう一方のテーブルの列が実際に必要な場合はJOINを使用します。
SELECT DISTINCT c.name
FROM customers c
JOIN orders o ON o.customer_id = c.id;インデックスが成否を分ける
インデックスに触れなければ、パフォーマンスについての回答は不十分です。相関したEXISTSは外側の各行について内部検索を実行するため、相関列、ここではorders(customer_id)にインデックスがあることが高速化の鍵になります。
「サブクエリが相関に使う結合列にインデックスを作成します」と述べれば、教科書的な回答が、面接官の評価する実践的な回答になります。
CREATE INDEX idx_orders_customer_id
ON orders (customer_id);面接での要点
次のように答えてください: 「EXISTSは、最初に一致する行で短絡評価する相関ブール判定です。一方、INは値のリストへの所属を確認します。正の判定では、最近のオプティマイザが同じセミJOINの実行計画を生成することがよくあります。実際の違いはNOT EXISTSとNOT INです。NOT EXISTSはNULLに安全なので、アンチJOINにはこちらを使用します。また、相関列にインデックスがあることを確認します。」
簡単な確認
EXISTSとINの議論の核心です。
まとめ
EXISTSとINの違いを整理しましょう:
EXISTSは、最初に一致する行で短絡評価する相関ブール判定です。内部のSELECTリストは関係ありません。INは値の集合への所属を確認し、小さく、重複がなく、非相関のリストに適しています。- 正の判定では、最近のオプティマイザが同じセミJOINの実行計画を選ぶことがよくあります。
- アンチJOINには
NOT INよりNOT EXISTSを優先してください — NULLに安全です。相関列にはインデックスを設定します。
これでSubqueries Deep Diveコースは終了です。
よくある質問
「EXISTSとINのパフォーマンス」レッスンは無料ですか?
はい。「EXISTSとINのパフォーマンス」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Coding Interview Prepコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Coding Interview Prepコースには全4レッスンが含まれています。
「EXISTSとINのパフォーマンス」で何を学びますか?
EXISTSが短絡評価によってINより高速になる場合を、シニア向け面接でよく出る質問として学びます。 ブラウザで直接実行するハンズオンコードでCoding Interview Prepを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Coding Interview Prepを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのCoding Interview Prepは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「EXISTSとINのパフォーマンス」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このCoding Interview Prepレッスンでコードを書いて実行できますか?
はい。すべてのCoding Interview Prepレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- SELECTとWHEREのスカラーサブクエリ
- FROM句のサブクエリ(派生テーブル)
- IN、ANY、ALLのサブクエリ
- EXISTSとINのパフォーマンス