【入門編】 ネステッドループ結合 – PostgreSQL

こんにちは!データベースの世界へようこそ。
普段、何気なくSQLを書いて「データを取ってくる」という作業をしていると、裏側でデータベースがどんなふうに頑張っているのか、なかなか想像しづらいですよね。

今日は、PostgreSQLがテーブル同士をくっつけるときに使う、一番シンプルで、でも奥が深い「ネステッドループ結合」についてお話しします。

専門用語を並べるのは一旦お休みして、ちょっとした日常の場面に例えてみましょう。

—

2つのリストを照らし合わせる作業

想像してみてください。あなたは今、「クラス名簿(テーブルA)」と、その生徒たちの「テストの点数表(テーブルB)」を突き合わせて、全員分の成績表を作ろうとしています。

さて、あなたならどんな手順で作業しますか?

きっと、こんなふうにやるはずです。

1. 名簿の一番上の生徒の名前を見る。
2. 点数表のリストを上から順に目で追って、その生徒の点数を探す。
3. 見つけたら成績表に書き込む。
4. 次に、名簿の2番目の生徒の名前を見る。
5. また点数表を上から順に見て、点数を探す……。

これを最後の人まで繰り返しますよね。
この「外側のリスト(名簿)を1行ずつめくりながら、そのたびに内側のリスト(点数表)を最初から最後までチェックする」というやり方。これがまさに、データベース界の「ネステッドループ結合(Nested Loop Join)」なんです。

—

なぜ「ネステッド」と呼ぶの?

「ネステッド(Nested)」とは「入れ子」という意味です。
プログラミングの世界でいう「ループの中にループがある」状態、つまり「二重ループ」のことですね。

先ほどの例で言うと……

  • 外側のループ:名簿を1人ずつ進める
  • 内側のループ:点数表を1件ずつ探す

この2つが重なっているので、ネステッドループと呼ばれます。シンプルでしょう?

—

このアルゴリズムの「得意」と「苦手」

このやり方は、とても直感的でわかりやすいですよね。でも、どんな仕事にも向き不向きがあるように、ネステッドループにも得意なシーンと、ちょっと厳しいシーンがあるんです。

得意なとき:小規模なとき

名簿が5人分しかなければ、この方法は最強に早いです。準備もいらないし、すぐに取り掛かれますからね。データベースでも、データ量が少ないときや、検索条件で「たった1人(または数人)」を特定できているときは、この方法が一番効率的です。

苦手なとき:大規模なとき

もし、名簿が1万人分あって、点数表も100万件あったらどうでしょう?
「1万人全員に対して、そのたびに100万行のリストを最初から最後まで探す」……。考えただけで気が遠くなりますよね。

もし名簿の生徒全員分をこのやり方でやろうとしたら、データベースは途方もない回数の「探し物」をすることになり、結果が出るまでにものすごく時間がかかってしまいます。

—

データベースの「賢い工夫」

実際のPostgreSQLは、この単純なネステッドループをもう少しだけ賢く使います。

もし、点数表のほうに「インデックス(索引)」がついていたらどうなるでしょうか?
点数表の最初から最後まで指でなぞる必要はなく、辞書を引くように「その生徒の点数」をパッと一瞬で見つけ出せますよね。

PostgreSQLは、インデックスが使える状態であれば、「ネステッドループ結合」を驚くほど高速にこなすことができるんです。

—

まとめ:今日のポイント

  • ネステッドループ結合は「二重ループ」:外側のテーブルを1行ずつ見ながら、内側のテーブルを都度確認するやり方。
  • 基本はシンプル:データ量が少ないときや、特定の行をピンポイントで探すときには最高のパフォーマンスを発揮します。
  • インデックスが命:データ量が多くなっても、内側のテーブルにインデックスがあれば、この手法はまだまだ現役で活躍できます。

「結合」と聞くと難しく感じますが、実は私たちが普段やっている「照らし合わせ作業」と何も変わりません。

「あ、今のクエリはネステッドループで動いてるんだな。ということは、内側のテーブルにインデックスを貼ったらもっと速くなるかも?」

そんなふうに、データベースの気持ちになって考えてみると、チューニングがぐっと楽しくなりますよ。ぜひ、皆さんの環境でも `EXPLAIN` コマンドを使って、PostgreSQLがどんなふうに結合しているのか覗いてみてくださいね!

それでは、また次回のブログでお会いしましょう。ハッピー・コーディング!

コメント

タイトルとURLをコピーしました