【テクニカル・上級編】 cpu_tuple_costの調整 – PostgreSQL

「デフォルト値」という名の罠:cpu_tuple_cost と最適化の深淵

PostgreSQLのチューニングにおいて、`work_mem` や `effective_cache_size` をいじるのは、いわば「基礎工事」のようなものだ。しかし、クエリの実行計画がどうしても直感に反する動きをするとき、我々エンジニアはパラメータの深層へ潜る必要がある。

今日は、そんな深淵の一つ、`cpu_tuple_cost` について話をしようと思う。

なぜ、プランナは「間違った選択」をするのか

PostgreSQLのプランナは、コストベースのオプティマイザだ。しかし、この「コスト」はあくまで見積もりに過ぎない。特に、大量のタプルをスキャンする際、デフォルトの `cpu_tuple_cost = 0.01` という値が、現代のハードウェア環境やデータセットの特性と乖離していることは珍しくない。

例えば、複雑なJOINや、大量の行をフィルタリングするクエリで、インデックススキャンではなくシーケンシャルスキャンが選ばれてしまうケース。あるいはその逆。なぜプランナはそれを選ぶのか。それは、プランナが「1タプルを処理するコスト」を、あなたのマシンの実際のCPUパフォーマンスに対して過小(あるいは過大)に見積もっているからだ。

cpu_tuple_cost が支配する領域

`cpu_tuple_cost` は、プランナがタプルを処理する際のCPUコストを定義する。具体的には、フィルタ条件の評価や、プロジェクションの作成などだ。

ここでのポイントは、この値が 「行数が増えれば増えるほど、雪だるま式に実行計画の選択に影響を与える」 という点だ。

  • 小規模なテーブル: ここでは `cpu_tuple_cost` の影響は軽微だ。I/Oコスト(`seq_page_cost` など)が支配的になるためだ。
  • 数百万行を超えるテーブル: ここが戦場だ。`cpu_tuple_cost` がわずかに低いだけで、プランナは「シーケンシャルスキャンしてフィルタしたほうが、ランダムアクセスを伴うインデックススキャンより安い」と判断しやすくなる。

特に、NVMe SSDが普及し、ランダムアクセスのコストが劇的に下がった現代において、PostgreSQLのデフォルト値が「ディスクI/Oがボトルネックだった時代」のまま止まっていることは、我々が意識すべきギャップだ。

パフォーマンスチューニングの実践的アプローチ

もし、あなたのシステムで「明らかに効率の悪いフルスキャン」が頻発しているなら、まずは `EXPLAIN (ANALYZE, BUFFERS)` を見てほしい。見積もりコストと実際の実行時間に乖離がある場合、`cpu_tuple_cost` を調整する価値がある。

ただし、安易にグローバルな値を変更するのは禁物だ。これはデータベース全体、つまり全てのクエリに影響する劇薬だからだ。

1. 特定のセッションでのテスト

まずは、特定のクエリに対して、`SET LOCAL cpu_tuple_cost = 0.005;` のように値を下げて実行計画を見てみてほしい。もしこれで、プランナがより適切なインデックスを選ぶようになるなら、それはモデルが現実の処理能力に近づいたという証拠だ。

2. 計算の重み付けを考える

最近のPostgreSQLのバージョンでは、`cpu_operator_cost` や `cpu_index_tuple_cost` も存在する。これらとのバランスが重要だ。単純に `cpu_tuple_cost` だけをいじるのではなく、「なぜそのタプル処理が重いのか」を考える必要がある。JSONB型の複雑な操作や、重い演算子が含まれているなら、`cpu_operator_cost` の調整の方が効くこともある。

最後に:魔法の数字はない

「じゃあ、結局いくらに設定すればいいんだ?」という質問が聞こえてきそうだが、残念ながら答えはない。

データベースのチューニングに「ベストプラクティス」という言葉は、往々にして「思考停止」の別名だ。ストレージの種類、CPUのクロック数、メモリ帯域、そして何より「テーブルの行数と検索頻度のバランス」。これらすべてが、その環境における最適な `cpu_tuple_cost` を決定する。

私がアドバイスできるのは、「プランナを信じすぎないこと」だ。
デフォルト値は、あくまで一般的なケースを想定した「平均値」に過ぎない。あなたのデータベースは、世界にたった一つしかない、独自のデータ構造とクエリ負荷を持っているはずだ。

その特性を理解し、パラメータを微調整し、実行計画が「狙い通りの動き」に収束したときの快感。それこそが、データベースエンジニアという職種の醍醐味ではないだろうか。

皆さんのクエリが、今夜もインデックスの上を軽快に駆け抜けることを願っている。

コメント

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