統計情報という名の「羅針盤」:PostgreSQLプランナの裏側を覗く
PostgreSQLを長く触っていると、ある日突然クエリが遅くなる現象に遭遇します。インデックスは適切に貼られているはずなのに、プランナが頑なにシーケンシャルスキャン(Seq Scan)を選択する。そんな時、多くのエンジニアがまず疑うのが「統計情報の鮮度」です。
今日は、PostgreSQLのオプティマイザがどのように意思決定を行い、我々がその「羅針盤」をどうメンテナンスすべきか、少し深い話をしようと思います。
プランナは「計算」で世界を見ている
まず前提として、PostgreSQLのプランナは直感で動いているわけではありません。膨大な組み合わせの中から最もコストが低い実行計画を選ぶ、純粋な数学的計算を行っています。
ここで重要なのが、`pg_class`や`pg_statistic`(あるいはユーザー向けの`pg_stats`)に格納されているデータです。プランナはこれらの統計情報をもとに、「この条件を満たす行数は何件か?」「インデックスを使った方がI/Oコストが低いか?」を算出します。
もし統計情報が実データと乖離していれば、プランナは「インデックスを使ってもコストが高い」という誤った判断を下します。これが、インデックスが無視される最大の理由の一つです。
pg_statsを読み解く:プランナが見ている「景色」
`pg_stats`を眺めることは、データベースの健康診断に似ています。特に注目すべきは以下のカラムです。
- `n_distinct`: そのカラムに含まれる一意の値の数。これが不正確だと、プランナはカーディナリティ(選択性)を見誤ります。
- `most_common_vals` (MCV) と `most_common_freqs` (MCF): 頻出する値とその出現頻度。ヒストグラムだけではカバーできない偏りをこれで補完しています。
- `histogram_bounds`: 値の分布。範囲検索(`>` や `<`)のコスト見積もりに不可欠です。
例えば、あるカラムの分布が極端に偏っている場合、`ANALYZE`によるサンプリングが上手くいかず、特定の値を指定した時にプランナが「全件走査したほうがマシだ」と判断することがあります。`ALTER TABLE … ALTER COLUMN … SET STATISTICS` で統計情報の解像度を上げてやる必要があるのは、まさにこの「偏り」を正しくプランナに伝えるためです。
コスト計算の「重み」を理解する
PostgreSQLのコストモデルは、デフォルトでページアクセスを基準にしています。
- `seq_page_cost` (デフォルト 1.0)
- `random_page_cost` (デフォルト 4.0)
この比率が示すのは、「ランダムアクセスはシーケンシャルアクセスの4倍コストがかかる」という設計思想です。しかし、現代のストレージ環境において、この比率は本当に適切でしょうか? NVMe SSD全盛の今、`random_page_cost`を1.1や1.2まで下げたほうが、プランナがインデックスを積極的に活用してくれるケースは多々あります。
ただし、ここをいじるのは諸刃の剣です。安易な変更は他のクエリの実行計画を狂わせる可能性があるため、必ず`EXPLAIN ANALYZE`で検証し、変更の影響範囲を慎重に見極める必要があります。
パフォーマンストラブルシューティングの定石
もしあなたが今、クエリの遅さに頭を抱えているなら、以下のステップを踏んでみてください。
1. `EXPLAIN (ANALYZE, BUFFERS)` を実行する: 実際に読み込んだブロック数と、プランナが見積もった行数(`rows`)に大きな乖離がないか確認してください。ここがズレていれば、統計情報が犯人です。
2. `ANALYZE`の強制実行: テーブルの更新頻度が高い場合、自動バキュームの閾値を待たずに手動で`ANALYZE`をかけ、改善するか確認します。
3. 相関(Correlation)の確認: `pg_stats.correlation`を確認してください。インデックスの順序とデータの物理的順序がバラバラだと、ランダムアクセスが多発し、コストが跳ね上がります。この場合、`CLUSTER`コマンドで物理的な並び替えを検討するのも一つの手です。
最後に:技術は「感覚」で語るな
データベースエンジニアとして最も警戒すべきは、「たぶんこれで速くなるはずだ」という感覚論です。
PostgreSQLは非常に論理的で、誠実なシステムです。統計情報を正しく与えれば、必ずそれに沿った最適な答えを返してくれます。プランナがなぜその選択をしたのか。その背景にある統計という名の「羅針盤」を常に疑い、チューニングしていくことこそが、最高峰のパフォーマンスを導き出す唯一の道だと私は信じています。
皆さんのクエリが、今日も効率的なプランで実行されますように。
コメント