0Pricing
Coding Interview Prep · レッスン

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. SELECTとWHEREのスカラーサブクエリ
  2. FROM句のサブクエリ(派生テーブル)
  3. IN、ANY、ALLのサブクエリ
  4. EXISTSとINのパフォーマンス
← Coding Interview Prepに戻る