【実務・中級編】 パラレルクエリ設定 (max_parallel_workers等) – PostgreSQL

PostgreSQLのパラレルクエリと「仲良く」なるためのチューニング術

最近、後輩からこんな相談を受けました。「PostgreSQLでクエリが遅いからパラレルクエリを有効にしたいんだけど、どの値をいじればいいか分からなくて……」と。

わかる。すごくよくわかるよ。パラメータ設定画面を眺めていると、どれもこれも「性能が上がりそう」な魔法の数字に見えてくるよね。でも、ここを適当に設定すると、かえってシステム全体がガタガタになることもある。

今日は、PostgreSQLのパラレルクエリを実務レベルでどう制御していくか、教科書には書いていない「現場の肌感覚」を交えて話していくよ。

—

パラレルクエリの基本:心構え

PostgreSQLのパラレルクエリは、大きなテーブルをスキャンするときに、複数のワーカースレッド(プロセス)を立ち上げて「分担作業」させる機能だ。

でも、忘れないでほしいのは「並列化=コスト」だということ。プロセスを立ち上げるためのメモリやCPUのオーバーヘッドがあるから、小さなテーブルに並列処理を適用しても、逆に遅くなる。これを理解した上で、パラメータを調整していこう。

—

チューニングの主役たち

まずは、触るべきパラメータを整理するね。

1. `max_parallel_workers`:
システム全体で使える並列ワーカースレッドの最大数。これはサーバーのコア数に合わせて設定するのが基本だ。
2. `max_parallel_workers_per_gather`:
1つのクエリにつき、最大で何個のプロセスを動かすか。これが一番よく触る設定値だ。
3. `min_parallel_table_scan_size`:
「これくらいの大きさのテーブルなら、並列化しても元が取れるよね」という閾値。

—

実践:どう設定していくか?

僕が現場でよくやる手順はこんな感じだ。

1. まずは「土台」を決める

`max_parallel_workers` は、とりあえず「CPUのコア数」の半分〜同数程度を目安に設定する。ここを大きくしすぎると、クエリが走るたびにCPUが飽和して、OSのレスポンスまで悪くなるからね。

2. 「欲張り」すぎない値を設定する

`max_parallel_workers_per_gather` は、いきなり大きな値を入れないこと。まずは `2` か `4` あたりから始めるのが鉄則だ。

— 設定例:セッションごとに調整してテストしてみる
SET max_parallel_workers_per_gather = 4;
EXPLAIN ANALYZE SELECT FROM large_log_table WHERE status = ‘error’;

`EXPLAIN ANALYZE` を叩いてみて、`Workers Planned: 4` と出ているか確認してほしい。もし実行時間が短くなっても、CPU負荷が90%を超えて張り付くようなら、それは設定しすぎのサインだ。

3. 「小さなテーブル」の悲劇を防ぐ

デフォルトの `min_parallel_table_scan_size` は `8MB` だ。これが小さすぎると、インデックスが効かない小さなテーブルまで並列化しようとして、却って遅延を招くことがある。もし「あれ、意外と遅いな」と思ったら、ここを `64MB` や `128MB` に引き上げてみてほしい。

—

現場で遭遇する「落とし穴」

ここで、僕の苦い経験を一つ。
ある日、バッチ処理のクエリを速くしたくて、特定のクエリに対して `max_parallel_workers_per_gather` を強引に上げたら、DBサーバー全体のメモリが枯渇してOOM Killerにプロセスを殺されたことがあるんだ。

並列化は「メモリ」も食うってことを忘れないでほしい。

  • `work_mem` × `max_parallel_workers_per_gather` = 1つのクエリが消費するメモリの目安

この計算を頭の片隅に置いておくこと。設定をいじるときは、必ず「今のサーバーの空きメモリで、この並列数は安全か?」を自問自答してほしい。

—

最後に:チューニングは「観測」から

結局のところ、パラメータに「銀の弾丸(万能な値)」はないんだ。

  • `EXPLAIN ANALYZE` をとって、コストを眺める。
  • `pg_stat_activity` で、実行中のクエリの負荷を確認する。
  • 実際のアプリケーションの応答速度を計測する。

このサイクルを回すのが、結局一番の近道。最初は怖いかもしれないけれど、少しずつ数値をいじって、PostgreSQLがどう反応するかを楽しむくらいの余裕を持って向き合ってみて。

もし詰まったら、またいつでも聞きに来てよ。エンジニア同士、一緒に手を動かそう。

コメント

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