【実務・中級編】 プランナの定数設定 – PostgreSQL

「プランナのさじ加減」を理解する:PostgreSQLのCPUコスト定数と付き合う技術

やあ。最近、PostgreSQLのパフォーマンスチューニングで悩んでるって聞いたよ。
「インデックスも貼ったし、`VACUUM ANALYZE`も定期的に回してるのに、なぜか実行計画が変な方を選ぶ……」なんて経験、一度はあるよね。

実はPostgreSQLのオプティマイザ(プランナ)は、内部で「このクエリを実行するのにどれくらいのコストがかかるか」を数値化して比較しているんだ。この計算式の中核を担っているのが、`postgresql.conf`にひっそりと鎮座する「コスト定数」たちだ。

今日は、その中でも特に重要で、かつ「沼」にハマりやすいCPU関連のコスト定数について、現場の知見を交えて話していくよ。

—

なぜデフォルト値が「最適ではない」ことがあるのか

まず大前提として。PostgreSQLのコスト定数のデフォルト値は、あくまで「一般的なハードウェア」を想定した汎用的なものだ。
もし君の環境が、超高速なNVMe SSDを積んだ最新鋭のサーバーなのか、それとも安価なクラウドインスタンスなのかによって、最適な計算式は変わってくる。

特に今回紹介する以下のパラメータは、クエリの実行計画に直接「重み付け」をするものなんだ。

  • `cpu_tuple_cost`: 行(タプル)を処理するコスト。
  • `cpu_index_tuple_cost`: インデックス経由で行を処理するコスト。
  • `cpu_operator_cost`: クエリ内の演算(WHERE句の条件比較など)にかかるコスト。

—

「プランナの判断」を左右する定数の正体

例えば、プランナが「フルテーブルスキャン」と「インデックススキャン」のどちらが速いかを判断する時、内部ではこんな計算が働いている。

コスト = (ページ読み込みコスト) + (行を処理するCPUコスト)

もし君のデータベースが「インデックスを貼っているのに、なぜかフルスキャンを選択する」という挙動を見せているなら、プランナは「インデックスを使って大量のタプルを読み出すよりも、シーケンシャルにメモリに乗せて回した方がCPUコスト的に安い」と判断している可能性が高い。

ここで調整の出番だ。

1. `cpu_tuple_cost` を調整するケース

デフォルトは `0.01` だ。この値を少し上げると、プランナは「行を走査するコストは高い」と認識するようになる。結果として、「できるだけ行に触りたくないから、インデックスを積極的に使おう」という思考回路に誘導できるんだ。

2. `cpu_index_tuple_cost` を調整するケース

デフォルトは `0.005`。インデックスのスキャンコストだね。
もしインデックスの断片化が進んでいたり、インデックスの階層が深すぎてアクセス負荷が高いと感じるなら、この値を少し上げることで、過度なインデックススキャンを抑制し、テーブルアクセスへ誘導することもできる。

—

実践:設定を変える前にやるべきこと

ここで一つ、先輩として釘を刺しておきたい。
「いきなり本番環境でこれらをいじるのは絶対にやめてくれ」。

コスト定数の変更は、影響範囲がデータベース全体に及ぶ。あるクエリが速くなった裏で、別の重要なバッチ処理が激遅になる……なんていうのは「あるある」だ。

まずは検証環境で、`SET`コマンドを使ってセッション単位でシミュレーションするのが鉄則だよ。

— 検証用クエリの実行計画を確認
EXPLAIN ANALYZE SELECT FROM users WHERE status = ‘active’;

— 一時的にコスト定数を変更して、プランの変化を見る
SET cpu_tuple_cost = 0.05;

— 再度実行計画を確認
EXPLAIN ANALYZE SELECT FROM users WHERE status = ‘active’;

もしこれで狙った実行計画(インデックススキャンなど)が選ばれるようになったら、初めてパラメータ変更を検討するステージに立てたと言える。

—

最後に:定数調整は「最後の手段」

現場で長く働いていると、「コスト定数をいじれば魔法のように速くなる」と勘違いしているエンジニアによく出会う。でも、実際はそんなことないんだ。

プランナが変な計画を立てる最大の原因は、実は「統計情報の不一致」であることが9割だ。まずは`ANALYZE`をかけて、テーブルの行数やデータの偏りが正確にプランナに伝わっているかを確認しよう。

それでも解決しない、特定のインデックスがどうしても使われない……そんな「どうしようもない状況」の時に初めて、このコスト定数という「スパイス」を微調整する。これが、プロのチューニングだよ。

もし設定を変えるなら、変更前と変更後の実行計画を必ずログに残して、経過観察を忘れないようにね。

また何か詰まったら、いつでも聞きに来てくれ。一緒にクエリの裏側を覗いていこうぜ。

コメント

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