なぜ、「デフォルト」の統計情報だけでは足りなくなるのか?
PostgreSQLのクエリオプティマイザは、間違いなく世界で最も賢い仕組みの一つです。しかし、どれほど優秀なプランナーであっても、統計情報という「地図」が不正確であれば、迷走するのは避けられません。
皆さんも経験があるはずです。「インデックスは貼ってあるし、`EXPLAIN ANALYZE`を見てもコスト見積もりが明らかに実態と乖離している」。そんな時、真っ先に疑うべきは統計情報の粒度です。
今日は、PostgreSQLの統計情報の「解像度」を局所的に高める、`ALTER TABLE … ALTER COLUMN … SET STATISTICS` という、いぶし銀なチューニング手法について掘り下げてみたいと思います。
—
統計情報のデフォルトを疑え
PostgreSQLにおいて、統計情報のサンプリング精度を決めるのが `default_statistics_target` です。デフォルト値は「100」。これは、ヒストグラムを作成するために使われるバケットの数に直結します。
ほとんどのテーブルでは、これで十分です。しかし、データの分布が極端に偏っていたり、あるいは「非常に稀だが、クエリの実行計画を左右する重要なキー」が存在する場合、デフォルトの100ではヒストグラムの分解能が足りず、プランナーは「カーディナリティの推定ミス」という罠に落ちます。
特に、以下のようなケースでは要注意です。
- ロングテールな分布: ほとんどのデータが特定の数値に集中し、ごく一部のユニークな値が外れ値として存在する。
- 相関のない複雑なクエリ: 複数のカラムにまたがる条件で、統計情報の解像度不足がプランの崩壊を招く。
SET STATISTICS で解像度を上げる
特定のカラムの統計精度を上げたい場合、私たちは以下のようにコマンドを叩きます。
ALTER TABLE orders ALTER COLUMN status_code SET STATISTICS 500;
ANALYZE orders(status_code);
ここで重要なのは、「闇雲に値を上げないこと」です。
内部アーキテクチャから考える「コスト」
`SET STATISTICS` の値を大きくすると、以下のトレードオフが発生します。
1. ANALYZEの負荷: `ANALYZE` 実行時にスキャンするサンプルの行数が増え、システムカタログ(`pg_statistic`)への書き込み負荷が増大します。
2. カタログサイズ: `pg_statistic` テーブルが肥大化し、統計情報のロード時間やメモリ消費に影響を与えます。
最大値は1000ですが、私は通常、300〜500あたりから試すことを推奨しています。1000まで上げると、`ANALYZE` のオーバーヘッドが無視できなくなるケースが多いからです。
—
トラブルシューティングの勘所
私が現場でよく行う、この手法の適応判断プロセスは以下の通りです。
1. プランの乖離を確認: `EXPLAIN ANALYZE` を実行し、`rows`(推定行数)と `actual rows`(実行数)を比較する。ここが数桁違うなら、統計情報の問題である可能性が高い。
2. pg_stats を覗く: `SELECT n_distinct, most_common_vals, histogram_bounds FROM pg_stats WHERE tablename = ‘…’ AND attname = ‘…’;` を確認する。ヒストグラムのバケットが十分に細分化されているか、あるいは `most_common_vals` に必要な値が含まれているかを確認します。
3. 相関統計の検討: もし、カラム間の相関が原因であれば、`CREATE STATISTICS`(マルチカラム統計)の方が適している場合があります。ここを混同してはいけません。
最後に:職人の道具としての統計情報
`ALTER COLUMN … SET STATISTICS` は、まさに「外科手術」のようなものです。全体に対して設定を変えるのではなく、問題のあるカラムだけをピンポイントで最適化する。これは、データベースの内部構造を理解し、クエリがどう解釈されるべきかをイメージできているエンジニアにしか許されない特権です。
パフォーマンスチューニングは、魔法ではありません。データがどう分布し、オプティマイザがどう読み取っているのか。その「情報の齟齬」を埋めるという、極めて地味で、しかし確実な作業の積み重ねです。
ぜひ皆さんの環境でも、`EXPLAIN` の数字が乖離している箇所を見つけたら、この「解像度の調整」を試してみてください。驚くほどクエリが軽くなる瞬間を、きっと味わえるはずです。
それでは、良いチューニングライフを。
コメント