「あれ、なんか遅い…」と思ったらここを見ろ!PostgreSQLの隠れた功労者『temp_buffers』の話
現場でバリバリとクエリを書いていると、複雑な集計や中間データの保存のために、つい「一時テーブル(Temporary Table)」に頼りたくなるときってありますよね。
`CREATE TEMP TABLE tmp_results AS SELECT …`
これ、便利なんです。でも、ある日突然、大量のデータを扱うバッチ処理で「なんか妙にディスクI/Oが跳ね上がってるな?」と感じたことはありませんか?実はそれ、PostgreSQLの設定値である `temp_buffers` がボトルネックになっている可能性が高いんです。
今日は、教科書にはあまり詳しく書かれていない、でも現場では死活問題になる「temp_buffers」について、実務的な視点で深掘りしてみましょう。
—
temp_buffers ってそもそも何者?
簡単に言うと、「そのセッションが使う一時テーブル専用のメモリ領域」です。
PostgreSQLには `shared_buffers` という全セッション共通のメモリ領域がありますが、一時テーブルは「そのセッション専用」なので、わざわざ共有メモリに置く必要がない。そこで、セッションごとに専用のメモリ領域を確保して、高速に読み書きさせようというのがこの設定の狙いです。
デフォルト値は通常 `8MB` です。…正直言って、今の時代、これはかなり控えめです。
なぜこれが問題になるのか?
もし、あなたが一時テーブルで数万行、あるいは数十万行のデータをガッツリ扱っているとします。
1. データが `temp_buffers` の容量(8MB)を超えてしまう。
2. PostgreSQLは「あ、メモリに入り切らないや」と判断し、溢れた分を物理ディスク(一時ファイル)に書き出し始める。
3. ディスクI/Oが発生し、処理が一気に重くなる。
この「メモリからディスクへ溢れる」という挙動こそが、パフォーマンス低下の真犯人なんです。特に、複雑なJOINやWindow関数を多用する分析クエリでは、メモリを食いつぶすのは一瞬です。
—
実践:どうやってチューニングする?
チューニングの基本は「どれだけ溢れているかを可視化すること」です。まずは、ログを確認してみてください。
`postgresql.conf` で `log_temp_files` を `0` に設定して再起動すれば、一時ファイルが作成されるたびにログに記録されます。
— 設定例:0を指定すると、すべての一時ファイル生成がログに出る
— 実際は運用に合わせて 1024KB くらいから様子を見るのがおすすめ
ALTER SYSTEM SET log_temp_files = ‘0’;
SELECT pg_reload_conf();
ログに `temporary file: size XXXXX` と頻繁に出ているなら、それが改善のサインです。
具体的な設定変更の目安
もし、あなたのシステムが以下のような構成なら、数値を上げることを検討してください。
- バッチ処理で巨大な一時テーブルを頻繁に作成する
- メモリに余裕があるサーバー(32GB以上積んでるなど)
— セッション単位で設定を試すことも可能
SET temp_buffers = ’64MB’;
— バッチ処理の冒頭で設定するのもアリ
BEGIN;
SET LOCAL temp_buffers = ‘128MB’;
— ここで一時テーブルを使いまくる処理を実行
COMMIT;
ただし、注意点があります。`temp_buffers` はセッションごとに確保されるメモリです。例えば、同時に100セッションが動いている状態で `temp_buffers` を `256MB` に設定すると、理論上は `256MB 100 = 25GB` のメモリを消費する可能性があります。
「とにかく大きくすればいい」ではなく、「そのプロセスが最大でどれくらいの一時データを扱うか」を見極めて、少し余裕を持たせるのがプロの仕事です。
—
先輩からのアドバイス:そもそも一時テーブルが必要?
最後に、ちょっと意地悪な質問をさせてください。
「その一時テーブル、本当に必要ですか?」
PostgreSQLのクエリプランナは優秀です。一時テーブルを使わなくても、WITH句(CTE)や、うまくインデックスを貼ったサブクエリで同じ結果を、もっと速く出せるケースも多いです。
1. まずは `EXPLAIN ANALYZE` で実行計画を確認する。
2. 一時テーブルを使わない書き方を試す。
3. それでもダメなら、`temp_buffers` をチューニングする。
この手順を守るだけで、あなたの書くSQLは一段階上のクオリティになりますよ。
データベースエンジニアとしての腕の見せ所は、単に設定をいじることではなく、「いかにリソースを使わず、最短で結果を出すか」を考えることにあると僕は信じています。
皆さんの現場のパフォーマンスが、少しでも改善しますように。また次回の記事でお会いしましょう!
コメント