こんにちは!データベースの世界へようこそ。
普段、何気なく書いているSQL。「なんでこのクエリ、こんなに遅いの?」なんて思ったことはありませんか?
今日は、PostgreSQLが裏側で頑張っている「ハッシュ結合」という仕組みと、それを影で支える「work_mem(ワークメモリ)」という設定について、ちょっと面白い例え話を交えてお話ししますね。
—
料理店で例えると?「ハッシュ結合」の正体
想像してみてください。あなたは今、大忙しのレストランの料理長です。
そこに「注文リスト(テーブルA)」と「食材リスト(テーブルB)」が届きました。この二つを突き合わせて、正しい料理を作り上げなければなりません。
このとき、PostgreSQLがよく使うのが「ハッシュ結合」という手法です。
1. まず、片方のリスト(小さい方)を手に取ります。
2. その食材を、すぐに取り出せるように「作業台(メモリ)」の上にきれいに並べます。これが「ハッシュテーブル」を作るという作業です。
3. 次に、もう片方のリストを一枚ずつ手に取り、「お、この食材はさっき並べたあれとペアだ!」と確認して、料理を仕上げていきます。
これ、すごく効率的ですよね。何度も行ったり来たりしなくていいんですから。
—
「作業台」が狭いと、地獄が始まる
さて、ここで重要になるのが「作業台(work_mem)」の広さです。
この作業台、実はPostgreSQLの設定値で決まっています。「これくらいあれば足りるでしょ」と決めた広さ(work_mem)が、もし食材の数に対して狭すぎたらどうなるでしょうか?
- 「あ、作業台に乗らない!」
- 仕方がないので、乗らなかった分を一旦「裏の倉庫(ディスク)」に片付けに行きます。
- 「あの食材どこだっけ?」と、わざわざ倉庫まで取りに行く……。
これをデータベースの世界では「Spill to disk(ディスクへの溢れ)」と呼びます。
想像するだけで嫌ですよね。高速なメモリの上で作業しているのに、わざわざノロノロと動くディスクにアクセスしに行くわけですから。クエリが急に遅くなる最大の原因の一つは、だいたいこれです。
—
どうすればいい?賢い「作業台」の使いかた
じゃあ、「作業台をめちゃくちゃ広くすればいいじゃない!」と思いますよね。その気持ち、痛いほどよくわかります。でも、ちょっと待ってください。
実はこの作業台、「クエリが動くたび」に確保されます。もし同時に100人がアクセスしてきて、全員が巨大な作業台を広げ始めたら……サーバーのメモリは一瞬でパンクしてしまいます。
だからこそ、こんなふうに考えるのがコツです。
- まずは現状を知る: `EXPLAIN ANALYZE` という魔法のコマンドを使ってみましょう。「Disk: … spilled」なんて表示が出ていたら、それが「倉庫に行っちゃったよ」という合図です。
- ピンポイントで広げる: 全体の作業台を広げすぎてメモリ不足になるのは怖いですから、特定の重たいクエリだけ、「今からガッツリやるぞ!」という時に一時的に `SET work_mem = ’64MB’;` のように広げてあげるのがスマートです。
- インデックスを疑う: そもそも「食材」が多すぎて作業台に乗らないなら、もっと別の効率的な並べ方(インデックス)ができないか、見直してみるのも一つの手ですよ。
—
まとめ:心地よいデータベース運用のために
ハッシュ結合とwork_memの関係、なんとなくイメージできましたか?
データベースのチューニングって、難しい料理のレシピを調整するのと似ています。「作業台を広くするか」「食材の持ち込み方を工夫するか」。
機械的に設定をいじるのではなく、「今、PostgreSQLくんはどこで困っているのかな?」と想像してあげることが、高速化への一番の近道です。
もし今、あなたのクエリが「ディスクに溢れて泣いている」なら、ぜひ `work_mem` を少しだけ見直してあげてください。きっと、驚くほど軽快に動いてくれるはずですよ!
それでは、また次回の記事でお会いしましょう。ハッピーなクエリライフを!
コメント