こんにちは!データベースの世界にどっぷり浸かっているエンジニアです。
今日は、PostgreSQLの「ハッシュ結合(Hash Join)」という、ちょっと強そうな名前の仕組みについてお話しします。難しそうに聞こえるかもしれませんが、実は私たちの日常にある「ある工夫」と同じなんですよ。
さっそく、一緒に紐解いていきましょう!
—
ハッシュ結合って、つまり何なの?
例えば、あなたがものすごくたくさんの「名前」が書かれた名簿Aと、同じくらい大量の「住所」が書かれた名簿Bを突き合わせて、同じ人のデータを探そうとしていると想像してみてください。
これを力任せにやろうとすると、名簿Aの一人目を名簿Bの最初から最後まで探して、次に二人目を……なんてやっていたら、日が暮れてしまいますよね。データベースの世界では、これを「ネステッドループ」なんて呼んだりしますが、とにかく効率が悪い。
そこで登場するのが「ハッシュ結合」です。
準備がすべてを決める「整理術」
ハッシュ結合を例えるなら、「机の上に付箋を貼る」ような作業です。
1. まず、小さな方の名簿を手に取ります。
2. その名簿のデータを一つずつ読み込んで、「ハッシュテーブル」という名の「特製インデックス付きボックス」に放り込んでいきます。
3. 準備ができたら、もう片方の大きな名簿をペラペラとめくりながら、「この人はさっきのボックスにあるかな?」と確認していきます。
これなら、一回一回全部の名簿を探す必要はありません。ボックスの中身をチラッと見るだけで、「ある!」「ない!」が瞬時にわかるからです。すごく効率的だと思いませんか?
—
ここで登場!「work_mem」という名の「作業机」
さて、ここからがエンジニアの腕の見せ所です。
この「特製ボックス」を作る場所、実は「work_mem」という設定で決まる、データベース専用の「作業机」の上なんです。
- 作業机が広い(work_memが大きい)場合:
余裕たっぷりに全部のデータを広げられます。作業は一気に終わり、爆速で結果が返ってきます。
- 作業机が狭い(work_memが小さい)場合:
困ったことが起きます。机がすぐいっぱいになっちゃうんです。そうすると、データベースは「あ、これ以上載らないから、一旦書きかけのメモを一時的に床(ディスク)に置いておこう…」と、「ディスクへの退避」という作業を始めます。
これが、いわゆる「遅い!」の原因です。机の上だけで完結していた作業が、わざわざ床まで物を取りに行くようになるので、当然スピードはガクンと落ちてしまいます。
—
どうすればいいの?
「じゃあ、work_memをめちゃくちゃ大きくすれば最強じゃない?」と思いますよね。でも、ちょっと待ってください!
この「作業机」は、接続しているユーザー一人ひとりに割り当てられます。
もし、100人が同時にアクセスしているときに、みんなの机を巨大にしてしまったら……? サーバーのメモリがパンクして、データベース全体が動かなくなってしまうんです。
チューニングのコツ
初心者の方がまず意識してほしいのは、この2点です。
- 「慢性的におそいクエリ」を見つける: `EXPLAIN ANALYZE` というコマンドを打ってみてください。「Disk: xxxx kB」といった表示が出たら、それは「机から溢れて床に置いたよ」という合図です。
- 少しずつ調整する: 最初から数GBなんて極端な設定は避け、まずは少しずつ増やして様子を見るのが鉄則です。
—
最後に
データベースのチューニングって、なんだか難しい数学のように思われがちですが、実は「どうやって整理整頓するか」という片付けの工夫に近いんです。
「メモリという限られた作業スペースを、どうやって効率よく使うか」。この視点を持つだけで、あなたの書くSQLは一段と洗練されたものになるはずですよ。
もし今、あなたのデータベースが少し重たいなと感じていたら、ぜひ「作業机(work_mem)は足りているかな?」と想像してみてください。きっと、解決のヒントが見つかるはずです!
それでは、また次回のブログでお会いしましょう。ハッピー・クエリライフを!
コメント