2025年12月2日火曜日

SQL Server サブクエリとJOINの使い分けを徹底解説|パフォーマンスと可読性の比較

どっちを使えば速い?SQL ServerのサブクエリとJOINの違いと使い分け方を徹底解説

SQL Serverで複数のテーブルを組み合わせてデータを取得する方法として、サブクエリ(副問い合わせ)JOINがあります。
どちらでも同じ結果を得られるケースが多いですが、構文や実行計画の違いにより、パフォーマンスや可読性に影響します。
この記事では、サブクエリとJOINの違い、使い分けの考え方、実務での選び方を初心者にもわかりやすく解説します。

目次

サブクエリとJOINの基本概念

サブクエリとは

サブクエリ(Subquery)は、SQL文の中に含まれる別のSELECT文のことです。
メインクエリに渡すための一時的な結果セットを生成します。


SELECT *
FROM Orders
WHERE CustomerID IN (SELECT CustomerID FROM Customers WHERE City = 'Tokyo');

この例では、内側のSELECT(サブクエリ)が「東京の顧客ID」を抽出し、外側のクエリでその結果を使っています。

JOINとは

JOINは、複数のテーブルを結合して1つの結果セットを作成する構文です。リレーショナルデータベースの基本操作です。


SELECT o.OrderID, c.CustomerName
FROM Orders AS o
INNER JOIN Customers AS c ON o.CustomerID = c.CustomerID
WHERE c.City = 'Tokyo';

同じ条件でもJOINを使えば、明示的にテーブルを結合して取得できます。

サブクエリの使い方と構文

① WHERE句でのサブクエリ

最もよく使われるのが、WHERE句で条件指定するタイプです。


SELECT ProductName, UnitPrice
FROM Products
WHERE CategoryID = (SELECT CategoryID FROM Categories WHERE CategoryName = 'Beverages');

サブクエリの結果が1行1列の場合、単一値として比較できます。

② INを使った複数行サブクエリ


SELECT ProductName
FROM Products
WHERE CategoryID IN (SELECT CategoryID FROM Categories WHERE ParentCategoryID = 1);

IN を使えば、複数行の結果も比較対象にできます。

③ SELECT句内のスカラーサブクエリ

SELECT句内に書くと、1行ごとにサブクエリを評価します。


SELECT 
    CustomerName,
    (SELECT COUNT(*) FROM Orders WHERE Orders.CustomerID = Customers.CustomerID) AS OrderCount
FROM Customers;

小規模なデータなら問題ありませんが、行数が多いと遅くなりやすい点に注意しましょう。

JOINの使い方と構文

① INNER JOIN(内部結合)

両方のテーブルで一致する行のみを取得します。


SELECT o.OrderID, c.CustomerName
FROM Orders AS o
INNER JOIN Customers AS c ON o.CustomerID = c.CustomerID;

② LEFT JOIN(左外部結合)

左側(メイン)のテーブルをすべて保持し、右側がNULLでも残します。


SELECT c.CustomerName, o.OrderID
FROM Customers AS c
LEFT JOIN Orders AS o ON c.CustomerID = o.CustomerID;

注文がない顧客も含めて一覧化したい場合に使用します。

③ RIGHT / FULL JOIN

必要に応じて、右外部結合(RIGHT JOIN)や完全外部結合(FULL JOIN)も使用できます。

サブクエリとJOINの処理の違い

実行計画上の動き

SQL Serverの最適化エンジンは、サブクエリでもJOINでも同じ論理結果になる場合、内部的に同等の実行計画を生成します。
そのため「常にJOINの方が速い」とは限りません。

比較項目 サブクエリ JOIN
可読性 シンプルな条件に向く 複雑な結合条件も整理しやすい
パフォーマンス 単純な比較ではJOINと同等 大規模データでは有利なケースが多い
使いどころ 部分的な条件抽出・存在確認 関連テーブルのデータ統合

EXISTSとJOINの違い

EXISTS を使ったサブクエリは、結合不要で存在確認だけを行う場合に有効です。


SELECT c.CustomerName
FROM Customers AS c
WHERE EXISTS (
    SELECT 1 FROM Orders AS o WHERE o.CustomerID = c.CustomerID
);

EXISTS は行の存在だけを確認するため、重複が多い場合にJOINより効率的なこともあります。

使い分けの判断基準(パフォーマンス・可読性)

① パフォーマンス優先ならJOINが基本

大量データや複数テーブルの結合では、JOIN の方が最適化エンジンに有利に働きやすい傾向があります。
サブクエリは1行ごとに評価される場合、パフォーマンス低下の原因になります。

② 可読性・独立性重視ならサブクエリ

サブクエリは、条件が明確で独立しているときに可読性が高くなります。
特に「特定条件の存在確認」「最新データ取得」など、部分的なデータ参照に適しています。

③ 実務での使い分けまとめ

  • JOIN:結合結果を表示・集計したいとき
  • EXISTS:存在確認だけ行いたいとき
  • サブクエリ:部分的なフィルタリングや動的条件にしたいとき

最終的には、実行計画(Ctrl + M) を確認して最適化されているか確認することが重要です。

まとめと次のステップ

学んだ内容の整理

  • サブクエリはクエリ内で別のSELECTを実行する仕組み。
  • JOINはテーブルを結合して1つの結果にまとめる。
  • SQL Serverでは最適化により、同じ結果なら性能差が出ないこともある。
  • 可読性・独立性重視ならサブクエリ、パフォーマンス重視ならJOIN。

参考リンク

SQL Server 解説用イメージ

0 件のコメント:

コメントを投稿