【実務・中級編】 cpu_operator_costの調整 – PostgreSQL

「またプランナが変な気を起こして、全件スキャンを始めやがった……」

そんな経験、一度や二度じゃないですよね。PostgreSQLのクエリチューニングをしていると、必ずぶつかる壁が「プランナの勘違い」です。特に、重い計算処理や独自の関数をWHERE句やSELECT句にガッツリ詰め込んだクエリで、インデックスを使ってくれない時のあの絶望感。

今日は、そんな時に最後の切り札となる`cpu_operator_cost`について、現場目線で深掘りしてみようと思います。マニュアルには載っていない、僕たちがどう向き合うべきかというお話です。

—

なぜプランナは「間違った」判断をするのか?

PostgreSQLのクエリプランナは、基本的に「コストベース」で動いています。彼らは「データにアクセスするコスト」と「CPUで計算するコスト」を天秤にかけて、一番安上がりなルートを選ぼうとします。

ここで重要になるのが、デフォルトで設定されているコスト係数たちです。

  • `seq_page_cost` (デフォルト: 1.0)
  • `random_page_cost` (デフォルト: 4.0)
  • `cpu_tuple_cost` (デフォルト: 0.01)
  • `cpu_operator_cost` (デフォルト: 0.0025)

この `cpu_operator_cost` は、演算子や関数を1回実行するのにかかるコストを示しています。

問題は、「PostgreSQLは、あなたが書いた関数の重さを正確には知らない」という点です。例えば、単純な `a + b` と、数千行の外部テーブルを引くような複雑なストアドプロシージャ。これら両方が、デフォルトでは同じ「0.0025」というコストとして計算されてしまうんです。これじゃあ、プランナも迷いますよね。

—

どんな時に調整すべきか?

正直に言います。`cpu_operator_cost` を安易にいじり回すのは、あまりおすすめしません。これはデータベース全体、あるいはセッション全体の設定なので、副作用が大きすぎるからです。

ただ、以下のようなケースでは検討の価値があります。

  • 「計算量が極端に多いクエリ」がボトルネックになっている場合
  • インデックスを使えば速いのに、プランナが「計算コストが安い」と勘違いして全件走査(Seq Scan)を選択し続ける場合

例えば、位置情報系の計算や、巨大なJSONBのパースをWHERE句で行うようなクエリですね。

—

実践:どうやって調整するか

全体設定を変える前に、まずは対象のセッションだけで試すのが鉄則です。

— まずは現状のプランを確認
EXPLAIN ANALYZE SELECT FROM heavy_table WHERE ST_Distance(geom, ‘…’) < 100; -- 試しにコストを上げてみる(デフォルトの10倍~100倍くらいに振ることが多いです) SET cpu_operator_cost = 0.025; -- 再度プランを確認 EXPLAIN ANALYZE SELECT FROM heavy_table WHERE ST_Distance(geom, '...') < 100; このように、計算コストを意図的に高く設定することで、「この演算子は重いから、なるべく実行回数を減らそう(=インデックスを使って絞り込もう)」とプランナに認識させることができます。 ---

注意:これは「対症療法」だということを忘れないで

ここが一番伝えたいことですが、`cpu_operator_cost` の調整は、あくまで「プランナへのヒント出し」に過ぎません。

もし可能なら、まずは以下を優先してください。

1. インデックスの工夫: `CREATE INDEX … ON table ((ST_Distance(geom, …)))` のように、計算結果そのものをインデックス化する(関数インデックス)。これが一番確実です。
2. クエリの書き換え: WHERE句で計算を行わず、計算済みのカラムを持つようにテーブルをリファクタリングする。
3. 統計情報の更新: `ANALYZE` が古くて行数が正しく見積もれていないだけ、というケースが実は8割です。

—

最後に

データベースチューニングにおいて、魔法の杖はありません。「コスト係数をいじれば速くなる」というショートカットに頼りすぎると、後で別のクエリで「なぜかインデックスが効かなくなった」という地獄を見ることになります。

`cpu_operator_cost` を触るのは、「どうしてもプランナが納得してくれない時の最後の一手」。そう割り切って使うのが、現場で生き残るエンジニアの作法かなと思います。

明日からのチューニング作業、少しでもこの知識が役に立てば嬉しいです。何か詰まったら、またいつでも聞いてください。一緒にプランナの心の中を覗いてやりましょう。

コメント

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