2026年1月25日日曜日

【DBスペシャリスト】結合アルゴリズム実践編:Nested Loopを劇的に速くする「インデックス」の秘密

 前回の記事では、結合の3大アルゴリズム(Nested Loop / Sort Merge / Hash)の概要について触れました。今回は、その中でも実務で最も頻繁に登場し、かつチューニングの要となる**「入れ子ループ法(Nested Loop Join)」**を深く掘り下げます。

まずは、試験でもよく問われる「高速化のポイント」を問題形式で確認してみましょう。




1. 今日のクイズ:入れ子ループ法の高速化


問題 入れ子ループ法(Nested Loop Join)において、結合処理を劇的に高速化するために最も効果的な対策はどれか?

(ア) 外側の表(駆動表)を事前に全件ソートする

 (イ) 内側の表の結合キーに対してインデックスを作成する

(ウ) ワークエリア(メモリ)のサイズを拡張する 

(エ) 等価結合を非等価結合(不等号など)に変更する


正解: (イ)内側の表の結合キーに対してインデックスを作成する




2. なぜ「内側のインデックス」が重要なのか?


入れ子ループ法の動きを思い出してみましょう。外側の表から1行取り出すたびに、内側の表を「探しに行く」のがこのアルゴリズムです。

  • インデックスがない場合: 外側の表が1,000件、内側の表が10,000件あると、最悪 1,000 × 10,000 = 1,000万回 のデータアクセスが発生します。これが「重いクエリ」の正体です。

  • インデックスがある場合: 内側の表を全件探す必要がなくなり、インデックスを使ってピンポイントでデータを見つけられます。計算量は劇的に減り、数秒かかっていた処理がコンマ数秒で終わるようになります。




3. 実務で差がつく「外側の表(駆動表)」の選び方


試験問題から一歩踏み込んで、現場で実行計画を見る際のポイントを解説します。入れ子ループ法では、どちらの表を「外側(駆動表)」にするかが運命を分けます。

鉄則:外側には「絞り込まれた後の件数」が少ない方を置く

例えば、「2024年の売上データ(100件)」と「商品マスタ(10万件)」を結合する場合を考えてみましょう。

  • 正解: 売上データを外側にする。ループ回数は100回で済みます。

  • 失敗: 商品マスタを外側にする。ループが10万回走り、システムに大きな負荷がかかります。




4. DB製品ごとの「インデックス」と「ヒント」


以前の記事でも触れましたが、実行計画が思い通りにいかない時の対処法をおさらいします。

  • Oracle: /*+ INDEX(テーブル名 インデックス名) */ というヒント句で、特定のインデックスを使うよう強制できます。

  • PostgreSQL: ヒント句は標準ではありませんが、統計情報を最新にする ANALYZE コマンドを実行することで、DBに「こっちの表の方が件数が少ないから外側にしよう」と正しく判断させることができます。

  • MySQL: STRAIGHT_JOIN という構文を使うと、FROM句に書いた順番通りに結合(左側を外側にする)を強制できます。




5. 見習いエンジニアの考察:理論がトラブルを救う


現場で「画面の表示が遅い!」と呼び出されたとき、真っ先に確認するのはこの**「インデックスのない入れ子ループ」**が発生していないかです。

SQLの書き方は間違っていなくても、データの増大や統計情報のズレによって、DBが最適な道を見失うことがあります。そんな時、今回学んだ「内側のインデックス」や「駆動表の選択」という理論を知っていれば、冷静に原因を突き止め、解決策(インデックス作成や統計更新)を提示できます。

試験勉強で得た知識が、現場のトラブルを解決する「最強の武器」に変わる瞬間です。




0 件のコメント:

コメントを投稿