【入門編】 結合アルゴリズム:ハッシュ結合 – PostgreSQL

こんにちは!データベースの世界へようこそ。

今日は、PostgreSQLの「裏側」でひっそりと、でもすごく重要な仕事をしている「ハッシュ結合(Hash Join)」という仕組みについてお話しします。

「結合(JOIN)」っていうと、なんだか難しそうに聞こえるかもしれませんね。でも大丈夫、実はこれ、皆さんが日常で無意識にやっている「整理整頓」と全く同じ考え方なんです。

—

1. そもそも「結合」って何?

例えば、手元に「全校生徒の名前リスト」と「今日の給食の献立表」があるとします。
「誰がどの給食を食べるか」を組み合わせたいとき、あなたはリストをどう見比べますか?

1. 名前リストの一人ずつに対して、献立表を最初から最後まで全部めくって探す……(これはめちゃくちゃ時間がかかりますよね!)
2. 献立表を頭の中で整理して、「あ、この番号の料理はこれだな」とすぐ分かるようにしておく。

この「2」の方法が、まさにハッシュ結合なんです。

2. ハッシュ結合の魔法:ハッシュテーブルを作る

PostgreSQLがハッシュ結合をするとき、まずやるのは「小さい方のデータを、検索しやすいようにバラして箱に入れる」ことです。これを「ハッシュテーブルの構築」と呼びます。

辞書を引くときに「あ行」「か行」…と分かれているからすぐに見つかるのと同じで、データをハッシュ関数という「分類器」に通して、小さなバケット(箱)にポイポイと放り込んでいくイメージです。

これさえ終われば、もう一方の大きなデータがやってきたとき、いちいち全部を探し回る必要はありません。「あ、このデータならあの箱を見ればいいんだな!」と、一瞬でペアを見つけ出せるようになるんです。

3. 「机の広さ」が勝負を決める(work_memの話)

ここで一つ、エンジニアが頭を悩ませるポイントがあります。それが「work_mem」です。

これは、この作業をするための「作業机の広さ」だと思ってください。

  • 机が広い場合: 全部を広げて一気に仕分けができるので、爆速です。
  • 机が狭い場合: ここで悲劇が起きます。箱が乗り切らなくなってしまうんです。

この「乗り切らない!」となったとき、PostgreSQLは仕方なく、入りきらなかった分を一旦引き出し(ディスク)に片付けます。これを「スピル(Spill to disk)」と呼びます。

例えるなら、料理中にまな板が狭すぎて、切った野菜を一度シンクに避難させて、また戻して……を繰り返している状態。当然、作業効率はガタ落ちしますよね。

4. チューニングのコツ:焦らなくて大丈夫

もし皆さんのデータベースでクエリが遅いな?と感じたら、まずはこの「机の広さ(work_mem)」が足りているか疑ってみるのが定石です。

ただ、ここで注意!「じゃあ机を無限に広くすればいいじゃん!」と思うかもしれませんが、それは禁物です。机を広げすぎると、今度は部屋(メモリ)が圧迫されて、他の作業ができなくなってしまいます。

  • まずは今の設定値を確認する
  • 実行計画(EXPLAIN)を見て、ディスクへの書き出しが発生していないか確認する
  • 必要であれば、少しずつメモリを割り当ててみる

このステップを踏むだけで、驚くほどクエリが速くなることがよくありますよ。

—

今日のまとめ

  • ハッシュ結合は「分類して整理する」ことで高速化する手法。
  • PostgreSQLは頑張ってメモリ(作業机)にデータを広げようとする。
  • 机からはみ出すとディスクへ書き出す(スピル)が発生し、急激に遅くなる。

データベースのチューニングって、なんだか「片付け」に似ていると思いませんか? 無理に詰め込まず、かといって場所を取りすぎず。そんなバランス感覚を磨いていくのが、エンジニアとしての醍醐味かもしれませんね。

皆さんのデータベースが、今日も軽快に動きますように!また次回の記事でお会いしましょう。

コメント

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