結合アルゴリズム — 2つの表を賢くつなぐ
「注文」表と「顧客」表を顧客IDでつなぐ——SQLでは JOIN の一言ですが、その裏でDBはどの行とどの行が一致するかを膨大に照合しています。同じ結合でも、やり方はネステッドループ・ハッシュ・ソートマージの3通り。それぞれの手数(比較回数)を数えながら、いつどれが速いのかを動かして理解します。
1. 総当たりでつなぐ — ネステッドループ結合
一番素朴なやり方。表Aの1行ごとに、表Bを先頭から全部見て一致を探します。二重ループなので比較回数は n × m。小さい表どうしや、片方が索引で一発に絞れるときは十分速いのですが、両方が大きいと手数が爆発します。
下で外側(A)と内側(B)のポインタが動く様子を見てください。緑の線が見つかった一致(結合される行ペア)です。
2. ハッシュで一発照合 — ハッシュ結合
もっと賢く。まず小さいほうの表Aのキーをハッシュ表に登録しておきます(ビルド)。次に表Bの各行のキーをハッシュして、同じ入れ物(バケツ)だけを覗いて一致を探します(プローブ)。ハッシュは平均 O(1) で入れ物にたどり着くので、全体の手数はおよそ n + m。総当たりの n×m から劇的に減ります。
下で、Aがバケツに入っていく構築と、Bが自分のバケツだけ調べる照合の2段階を見てください。
A.id = B.id のような等値結合では、ハッシュ結合が大きい表どうしの定番。弱点はハッシュ表がメモリに乗る前提であること(乗らなければ分割して処理する)と、< や > の範囲結合には使えないこと(同じ値しか同じバケツに来ないため)。
3. 並べてから突き合わせる — ソートマージ結合
3つめは、両方の表をキーで並べ替えてから、2本の指で先頭を突き合わせる方法。小さいほうの指を進めながら、一致したら結果に出す——各行を一度ずつ見るだけなので、マージ自体は n + m。ただし前もってソートに n log n かかります。
下で、まず両表が整列し、次に2つのポインタが小さいほうを追い越さないように進む様子を見てください。
4. いつどれが速い? — コスト比較
3つの方式に絶対の勝者はなく、表の大きさ・索引の有無・並び順で最適解が変わります。オプティマイザ(次のレッスン)はこの費用を見積もって方式を選びます。下で件数を動かし、比較回数がどう変わるかを見てください。
<, BETWEEN)はソートマージの独壇場だし、片方が数行なら索引付きネステッドループが最速。データがすでに索引順で整列済みならソートを省けてマージが圧勝する。方式の良し悪しは常に文脈しだい。
5. まとめ — 結合の道具箱
- ネステッドループ n×m:素朴だが小さい表・索引付き内側なら現役。片方が数行のとき最速。
- ハッシュ結合 n+m:等値結合で大きい表どうしの定番。メモリ前提・範囲結合は不可。
- ソートマージ n log n + m + …:ソートが要るが、整列済み入力や範囲結合・順序付き出力に強い。
- 絶対の勝者はない:大きさ・索引・並び順で最適が変わり、オプティマイザが費用を見積もって選ぶ。