【テクニカル・上級編】 コスト見積もりパラメータ – PostgreSQL

「デフォルト値」という名の妥協点:PostgreSQLコストモデルを支配せざるを得ない理由

PostgreSQLのクエリプランナを語る上で避けて通れないのが、いわゆる「コスト定数」の調整だ。`seq_page_cost`、`random_page_cost`、そして `cpu_tuple_cost`。これらは単なる設定値ではなく、PostgreSQLが物理世界をどう認識しているかを定義する「哲学」そのものだと言ってもいい。

多くのエンジニアが「なぜプランナはシーケンシャルスキャンを選んだのか?」「インデックスがあるのに、なぜ無視するのか?」という悩みに直面する。その答えのほとんどは、これらのパラメータが、稼働しているハードウェアの現実と乖離していることに起因している。

コスト定数が「世界」を定義する

PostgreSQLのオプティマイザは、非常に論理的だ。だが、その論理を支えるコストモデルは、あくまで「比率」で成り立っている。

  • `seq_page_cost` (デフォルト 1.0): シーケンシャルスキャンで1ページを読み込むコスト。
  • `random_page_cost` (デフォルト 4.0): ランダムアクセスで1ページを読み込むコスト。

この「4倍」という比率は、ハードディスク(HDD)が全盛だった時代の遺産だ。シークタイムという物理的な重荷を考慮すれば、ランダムアクセスはシーケンシャルに比べて圧倒的に遅い。しかし、現代のNVMe SSDを搭載したサーバーで、この比率をそのまま維持するのは滑稽にさえ思える。

SSD環境では、ランダムアクセスとシーケンシャルアクセスのコスト差はほぼゼロに近い。それなのにデフォルトのまま運用していると、プランナは「ランダムアクセスは高コストだ」と思い込み、不自然にシーケンシャルスキャンを優先してしまう。これが、インデックスが無視される典型的な理由の一つだ。

現場で直面する「最適化の罠」

パフォーマンスチューニングの現場では、私はよく `random_page_cost` を `1.1` や `1.0` まで下げることを提案する。特に大規模なインデックススキャンが期待される環境では、これだけでクエリプランが一変することがある。

しかし、ここで注意が必要だ。コスト定数をいじるということは、プランナの「物差し」そのものを変えるということ。

  • `cpu_tuple_cost` (デフォルト 0.01): 1行を処理するコスト。これを不用意にいじると、結合アルゴリズム(Nested LoopかHash Joinか)の選定に深刻な影響が出る。
  • `cpu_index_tuple_cost` (デフォルト 0.005): インデックス内の1行を処理するコスト。これが低すぎると、インデックススキャンが過剰に評価され、結果としてテーブルのランダムアクセスが多発し、システム全体が悲鳴を上げることになる。

私が見てきた多くの失敗例は、特定のクエリを速くするためにコスト定数を極端に調整し、結果として他の数千種類のクエリのプランを破壊してしまうケースだ。「部分最適は全体最適の敵」。これはデータベースのチューニングにおいても真理だ。

アーキテクチャの文脈で考える

プランナは、「どのデータがメモリに乗っていて、どれがディスクにあるか」を完全には把握していない。`shared_buffers` のヒット率をコスト見積もりに反映させるような高度な機能も存在するが、基本的には統計情報(`pg_stats`)とコスト定数の掛け算でプランが決まる。

もし、貴方の環境がクラウドのマネージドサービスで、ストレージのレイテンシが変動するような環境であれば、コスト定数を固定することはある種の「賭け」になる。そんな時、私はパラメータをいじる前に、まずは `effective_cache_size` の値がOSのキャッシュ容量と乖離していないかを確認する。ここが正しく設定されていないと、プランナは「インデックススキャンの方がコストが低い」と判断する材料を見失うからだ。

最後に:チューニングは「対話」である

コスト定数の調整は、データベースに対する「調律」だ。マニュアルを読み込んで理論値を設定するだけでは足りない。そのデータベースがどのようなI/O特性を持ち、どのような負荷パターンで動いているのか。その「声」を聞く必要がある。

`EXPLAIN ANALYZE` を叩き、実際の実行時間とプランナの見積もりコストを比較してほしい。見積もりが大幅に外れているなら、それは統計情報が古いのか、それともコストモデルが現実と乖離しているのか。

パラメータを触る前に、まずは自分の推測を疑うこと。そして、変更を加えた後は、必ずワークロード全体の影響を俯瞰すること。それが、世界最高峰のデータベースエンジニアへの第一歩だと私は信じている。

さて、貴方のデータベースの「物差し」は、今のハードウェアと正しく共鳴しているだろうか?

コメント

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