SQLを書いていると、「この処理はサブクエリで書くべきか、それとも JOIN を使うべきか」と悩む場面は少なくありません。
どちらも同じ結果を取得できるケースが多いため、何となく慣れている書き方を選んでしまう方も多いのではないでしょうか。
しかし、サブクエリと JOIN には明確な特性の違いがあり、状況によってはパフォーマンスや可読性、保守性に大きな差が出ることがあります。
本記事では、SQLにおけるサブクエリと JOIN の違いを整理し、速度面・可読性の観点から「どちらを使うべきか」を具体例とともに解説します。
サブクエリとは何か

サブクエリとは、SQL文の中に記述される別の SELECT 文のことです。
主に以下の場所で使用されます。
- WHERE 句
- SELECT 句
- FROM 句
サブクエリの基本例
|
1 2 3 4 5 6 7 |
SELECT * FROM orders WHERE customer_id IN ( SELECT customer_id FROM customers WHERE status = 'ACTIVE' ); |
この例では、先に customers テーブルから条件に合致する customer_id を取得し、その結果を使って orders を絞り込んでいます。
サブクエリの特徴
- 処理の流れを段階的に理解しやすい
- 条件を文章的に書けるため直感的
- 単純な抽出条件には向いている
- ネストが深くなると読みにくくなる
JOIN とは何か
JOIN は複数のテーブルを結合し、1つの結果セットとして扱うための構文です。
リレーショナルデータベースでは非常に基本的かつ重要な機能です。
JOIN の基本例
|
1 2 3 4 5 |
SELECT o.* FROM orders o JOIN customers c ON o.customer_id = c.customer_id WHERE c.status = 'ACTIVE'; |
上記は、先ほどのサブクエリと同じ結果を返します。
JOIN の特徴
- テーブル間の関係性が明確になる
- 複数テーブルを扱う処理に強い
- 最適化されやすい
- 書き方を誤ると意図しない件数になる
速度面での比較
結論から言うと
多くのケースでは JOIN の方が高速、または安定した性能を出しやすい傾向があります。
なぜ JOIN が有利になりやすいのか
データベースのオプティマイザは、JOIN を前提とした最適化に非常に強く設計されています。
インデックスの利用、結合順序の入れ替え、アクセスパスの選択などが柔軟に行われます。
一方、サブクエリは以下のようなケースで性能が劣化しやすくなります。
- 相関サブクエリを使用している
- サブクエリが行ごとに評価される
- 大量データを返すサブクエリ
相関サブクエリの例
|
1 2 3 4 5 6 7 8 |
SELECT * FROM orders o WHERE EXISTS ( SELECT 1 FROM customers c WHERE c.customer_id = o.customer_id AND c.status = 'ACTIVE' ); |
このような相関サブクエリは、実行計画によっては orders の行数分だけサブクエリが評価され、性能問題につながることがあります。
可読性での比較
単純な条件ならサブクエリ
以下のように、「ある条件を満たすID一覧に含まれているか」というケースでは、サブクエリは非常に読みやすくなります。
|
1 2 3 4 5 |
WHERE user_id IN ( SELECT user_id FROM users WHERE deleted = 0 ) |
処理内容を日本語にすると、「削除されていないユーザーに含まれるもの」となり、意図が明確です。
複数テーブル・複雑な条件なら JOIN
テーブルが3つ以上になったり、取得項目が増えたりする場合、サブクエリは急激に読みにくくなります。
|
1 2 3 4 5 |
SELECT o.order_id, c.customer_name, p.product_name FROM orders o JOIN customers c ON o.customer_id = c.customer_id JOIN products p ON o.product_id = p.product_id WHERE c.status = 'ACTIVE'; |
JOIN を使うことで、テーブル同士の関係性が一目で把握できます。
保守性・拡張性の観点
- JOIN は後から条件や取得項目を追加しやすい
- サブクエリはネストが増えると修正時に事故が起きやすい
- チーム開発では JOIN の方がレビューしやすい傾向がある
特に業務システムでは、後から要件が追加されることが前提になります。
将来の修正を考えると、JOIN をベースにした構成の方が無難です。
データベース別の注意点
- Oracle:JOIN とサブクエリの最適化は比較的優秀だが、相関サブクエリは注意
- MySQL:古いバージョンではサブクエリが最適化されにくいケースがある
- PostgreSQL:JOIN の最適化が非常に強力
どのDBでも「実行計画を確認する」ことが最重要です。
使い分けの指針まとめ
| 観点 | サブクエリ | JOIN |
|---|---|---|
| 単純な条件 | ○ | ○ |
| 複雑な結合 | △ | ◎ |
| パフォーマンス | △ | ◎ |
| 可読性 | 条件次第 | ◎ |
| 保守性 | △ | ◎ |
よくある質問(Q & A)
- サブクエリは使わない方が良いのですか?
-
いいえ。一概に悪いわけではありません。
単純な条件や EXISTS を使った存在チェックなど、適した場面では有効です。 - JOIN に書き換えれば必ず速くなりますか?
-
必ずではありません。
データ量、インデックス、実行計画によっては差が出ないこともあります。 - 相関サブクエリは避けるべきですか?
-
大量データを扱う場合は特に注意が必要です。
JOIN に置き換え可能であれば、検討する価値があります。 - 可読性は個人差がありませんか?
-
あります。ただし、チーム開発では JOIN の方が意図を共有しやすいケースが多いです。
まとめ
サブクエリと JOIN は、どちらが絶対に正しいというものではありません。
重要なのは「処理内容」「データ量」「将来の保守」を踏まえて適切に選択することです。
- 単純な条件や存在確認 → サブクエリ
- 複数テーブル・業務ロジック → JOIN
- パフォーマンスが重要 → 実行計画を必ず確認
SQLは書けることよりも、長く安全に使えることが重要です。
その視点で使い分けることが、実務では最も価値があります。


