SQLチューニングの基本:Nested Loops結合とインデックス活用のポイント
はじめに
SQLの結合処理において代表的なアルゴリズムの一つが*Nested Loops です。特に結合キーにインデックスがある場合、Nested Loopsは非常に効率的な手法となり得ます。
本記事では、Nested Loopsの動作原理と、パフォーマンスを最適化するためのインデックスの使い方について解説します。
Nested Loopsの基本動作
Nested Loopsは、結合対象の片方(外部テーブル)を1行ずつ処理し、対応するもう一方のテーブル(内部テーブル)に対してループでアクセスする手法です。
このとき、この内部テーブルの該当行にアクセスする方法として、インデックスが存在するかどうかが非常に重要なポイントになります。
インデックスの有無による違い
以下に、インデックスの有無による実行計画の違いをOracle/PostgreSQLの例で示します。
内部表にインデックスがある場合(Oracle)
NESTED LOOPS
TABLE ACCESS FULL (Table A)
INDEX RANGE SCAN (Table B)
この場合、インデックスを使ってTable Bに効率的にアクセスしています。
内部表にインデックスがない場合(PostgreSQL)
NESTED LOOPS
SEQ SCAN (Table B)
内部表にインデックスがないため、Table B全体をシーケンシャルスキャンする必要があり、パフォーマンスに悪影響が出ます。
内部表をスキップできるかが鍵
内部表にインデックスがあると、ループ内でのアクセス行数をスキップできる可能性があります。以下の図を見てください:
- インデックスが効いていて1行にアクセス → スキップが効く
- インデックスがあっても複数行にヒット
- → ある程度スキャンが必要
- インデックスがない → 全件スキャン
つまり、「内部表を小さくしよう」よりも「インデックスでスキップできるようにしよう」という発想の方が現実的です。
SQLチューニングの鉄則:組み合わせの設計
チューニングの基本は:
「外部表が小さい」×「内部表の結合キーにインデックスがある」
この組み合わせは、Nested Loopsのパフォーマンスを最大化する「黄金パターン」です。
よく使われる定番でありながら、非常に強力です。
まとめ
- Nested Loopsはインデックスの有無でパフォーマンスが大きく変わる
- 内部表が大きくても、インデックスによってスキップ可能なら効果あり
- テーブル設計時から「どのテーブルを外部表/内部表にするか」「どこにインデックスを張るか」を意識することが重要
SQLのパフォーマンスに悩んだら、「結合順序」と「インデックスの有無」をまず確認してみましょう。
参考
[SQL実践入門──高速でわかりやすいクエリの書き方 (WEB+DB PRESS plus)](https://www.amazon.co.jp/SQL%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E2%94%80%E2%94%80%E9%AB%98%E9%80%9F%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-WEB-DB-