JOINは、特定の条件に基づいて複数のテーブルを1つのSELECT文で結合することを可能にします。通常、ONというキーワードを介して行われます。サブクエリ(またはネストされたクエリ)は、別のクエリの内部に配置されたクエリです。JOINは、インデックスが適切に設定された大きなテーブルを結合する際により効果的で、オプティマイザにとっても透明性があり、通常はより速く実行されます。サブクエリは、集計計算が必要な場合や、JOINでは不可能な条件がある場合に便利です(例えば、相関サブクエリなど)。
JOINの例:
SELECT employees.name, departments.name FROM employees JOIN departments ON employees.dept_id = departments.id;
サブクエリの例:
SELECT name FROM employees WHERE dept_id IN ( SELECT id FROM departments WHERE location = 'Moscow' );
“サブクエリを使用することは、常にJOINを使用するよりも遅いと考えられていますか?”
回答: いいえ、必ずしもそうではありません!正しく書かれたサブクエリは、しばしばオプティマイザによって内部のJOINに変換されます。さらに、外部クエリが小さなデータセットを扱う際には、サブクエリがより効果的である場合もあります。例えば、サブクエリが事前に集計された結果を返す場合です。
例:
SELECT name, salary FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
このサブクエリは1回だけ実行されます。
事例
大規模プロジェクトの報告書では、JOINの代わりにネストされたサブクエリが使用されていました。データ量の増加に伴い、クエリの実行時間が数秒から数分に増えました。サブクエリをJOINに置き換えたところ、性能が10倍向上しました。
事例
あるプロジェクトでアナリストは、GROUP BYをサブクエリに書き換え、JOINレベルで重複が発生することに気づきませんでした。その結果、報告書のデータが不正確になり、合計がカーテジアン積によって過大評価されました。
事例
外部ループ(各行のため)で相関サブクエリを使用した結果、テーブルの増加に伴って性能が完全に低下しました。集計によるJOINに切り替えたところ、クエリの処理時間は数時間から数分に短縮されました。