PostgreSQLの並列クエリ、その「舞台裏」を覗いてみよう
やあ。最近、PostgreSQLのパフォーマンスチューニングで悩んでいないかな?
大規模なデータセットを扱うとき、クエリが1つのCPUコアだけで必死に頑張っているのを見て、「もっと効率よくできないのか?」ともどかしくなることはよくあるよね。そんなとき、PostgreSQLの「並列クエリ(Parallel Query)」という強力な武器を使いこなせているかどうかで、システムのレスポンスは劇的に変わる。
今日は、PostgreSQLが裏側でどうやって並列処理を組み立てているのか、その心臓部である`Gather`ノードやバックグラウンドワーカーの仕組みを、少し「中の人」の視点で掘り下げてみよう。
—
並列クエリの指揮官:「Gather」と「Gather Merge」
まずは実行計画を見ていてよく目にする`Gather`と`Gather Merge`について整理しておこう。これらは、言わば「散らばった作業を1つにまとめる指揮官」だ。
Gather:とにかく集める
`Gather`ノードは、複数のバックグラウンドワーカーが個別に実行した結果を、1つのプロセスに吸い上げる役割を担う。
例えば、単純なテーブルスキャンを並列で行ったとき、各ワーカーが読んできたデータ断片を、親プロセスが「はい、こっちへ寄せて」とまとめてクライアントに返すイメージだね。順序を気にしないなら、これが一番効率がいい。
Gather Merge:順序を維持して集める
一方で`Gather Merge`は、もう少し賢い。もしクエリが`ORDER BY`を伴っているなら、各ワーカーが個別にソートした結果を、マージソートの要領で「順序を保ったまま」統合するんだ。これがあるおかげで、並列処理をした後でも結果がバラバラにならずに済むわけだ。
—
舞台裏の働き手:バックグラウンドワーカーの正体
次に、実際に手を動かす「バックグラウンドワーカー」についてだ。
PostgreSQLが並列処理を決定すると、クエリを実行するプロセス(リーダープロセス)は、設定された数の「バックグラウンドワーカー」をフォーク(生成)する。このワーカーたちは、リーダーと同じ実行計画の断片をそれぞれ担当する。
ここで大切なのが、「リーダープロセス自身も作業に参加する」という点だ。
よく「ワーカーを3つに設定したから、合計4つで処理する」という計算になるんだけど、現場ではここを計算に入れ忘れてリソースを食いつぶすケースをよく見る。
実践:並列度を意識したチューニング
例えば、こんな設定を意識したことはあるだろうか?
— テーブルの並列度を一時的に上げてみる
ALTER TABLE logs SET (parallel_workers = 4);
— クエリの実行計画を見てみる
EXPLAIN ANALYZE
SELECT count() FROM logs WHERE created_at > ‘2023-01-01’;
もし`EXPLAIN`の結果に`Parallel Seq Scan`が出ていなければ、それはPostgreSQLが「並列化するメリットがない」と判断している証拠だ。よくある原因はこれだ:
1. データが少なすぎる: 小さなテーブルなら、プロセスを立ち上げるオーバーヘッドの方が高くつくからね。
2. costのしきい値: `min_parallel_table_scan_size`の設定が、テーブルサイズより大きくなっていないか確認してみよう。
3. 関数が並列非対応: `PARALLEL SAFE`属性がついていない関数をクエリ内で使っていると、並列化は即座に無効になる。これは罠にはまりやすいポイントだよ。
—
現場のエンジニアへ:一つだけのアドバイス
並列クエリは魔法じゃない。むしろ「諸刃の剣」だ。
並列度を上げれば上げるほど、CPU負荷は跳ね上がるし、メモリ(`work_mem`)もワーカーの数だけ消費される。もし1つのクエリで全てのCPUコアを使い切ってしまったら、その間、他のユーザーのリクエストが待たされることになるよね。
だから、僕がアドバイスしたいのはこれだ。
「まずは『なぜ並列化されていないのか』の理由を探り、次に『並列化によってシステム全体の負荷が許容範囲か』を考えること。」
性能が出ないからといって、やみくもに`max_parallel_workers_per_gather`を大きくするのはNGだ。まずは`EXPLAIN`をじっくり眺めて、PostgreSQLがどこでボトルネックを感じているのか、対話するように読んでみてほしい。
—
PostgreSQLは、中身を理解すればするほど、実に理にかなった動きをしてくれる面白いデータベースだよ。もし、特定のクエリで「ここがどうしても並列化されない!」という悩みがあれば、またいつでも聞いてくれ。一緒に実行計画を紐解こう。
それじゃ、今日はこの辺で。ハッピー・チューニング!
コメント