テック技報最新号へ →
コード

Postgres: 「Sort Method: external merge Disk」は work_mem を全体ではなくクエリ単位で上げる

EXPLAIN ANALYZE に Sort Method: external merge Disk: ...kB と出たら、ソートが work_mem に収まらずディスクにあふれている。ただし work_mem は接続ごとではなく「ソートやハッシュの操作 1 つごと」の上限なので、サーバー全体で上げるとメモリ不足を招く。必要なクエリだけ SET LOCAL で上げる。

@fastgridtrader · 投稿 2026-11-04
#postgres#performance#work_mem#infra

何が起きるか

複雑なクエリは、ソート・ハッシュ結合・ハッシュ集計を一度にいくつも実行する。それぞれが work_mem まで使えるうえ、ハッシュ系は hash_mem_multiplier(Postgres 15 以降の既定は 2.0)倍まで使える。パラレルワーカーがいればワーカーごとにさらに増える。「work_mem 256MB × 操作数 × 同時接続数」になるので、postgresql.conf で一律に上げると、ピーク時にメモリが一気に足りなくなる。

やり方

sql
-- まず確認
EXPLAIN (ANALYZE, BUFFERS) SELECT ... ORDER BY ...;
--   Sort Method: external merge  Disk: 182344kB   ← あふれている
--   Sort Method: quicksort  Memory: 2048kB        ← メモリ内で済んでいる

-- 重いレポートのクエリだけ、そのトランザクションの中で上げる
BEGIN;
SET LOCAL work_mem = '256MB';
SELECT ... ORDER BY ...;
COMMIT;   -- ここで元の値に戻る
  • バッチ処理など特定の用途だけで必要なら、専用のロールに ALTER ROLE report SET work_mem = '256MB'; と付ける手もある(考え方は Postgres: statement_timeout はアプリ用ロールに ALTER ROLE で設定する と同じ)。
  • 先にソート自体を減らせないかも見る。ORDER BY の列にインデックスがあれば、ソートなしで並んだ順に読める。

注意点

出典

X の元の投稿を開く