【実務・中級編】 統計情報収集のサンプリング手法 – PostgreSQL

大規模テーブルの「統計情報」でハマる前に。ANALYZEのサンプリングを攻略しよう

やあ。最近、PostgreSQLのパフォーマンスチューニングに頭を悩ませているメンバーが増えてきたね。

「クエリが急に遅くなった」「実行計画がめちゃくちゃになった」……そんな時、真っ先に疑うべきなのが統計情報(Statistics)だ。PostgreSQLのオプティマイザは、この統計情報を頼りに「どのインデックスを使うか」「どの結合順序が最適か」を判断している。

でも、数億行あるような巨大なテーブルに対して、毎回全行スキャンする `ANALYZE` を実行していたら、それだけで本番環境のCPUやI/Oを食い尽くしてしまうよね。

そこで今日は、PostgreSQLの「統計情報収集のサンプリング手法」について、現場の知恵を共有しようと思う。

—

そもそも、ANALYZEはどうやって統計を取っているのか?

`ANALYZE` を実行すると、PostgreSQLはテーブル全体をなめるわけじゃない。デフォルトでは、設定された割合(`default_statistics_target` に関連するパラメータ)に基づいて、テーブルの一部をランダムに抽出(サンプリング)して統計を推定しているんだ。

この「一部だけ見て全体を知る」という仕組み、実は理にかなっている。少量のデータで分布さえ正確に掴めれば、実行計画の精度は十分担保できるからね。

サンプリングの設定:何が鍵になるのか?

統計情報の精度をコントロールしたい時にいじるのが、`default_statistics_target` だ。

— 現在の統計取得ターゲットを確認
SHOW default_statistics_target;

デフォルトは `100` になっていることが多いはずだ。この数値が大きいほど、サンプリングする行数が増え、統計の精度は上がる。逆に小さくすれば、`ANALYZE` は爆速になるけど、データ分布の歪みに弱くなる。

現場で「あえて設定を変える」ケース

例えば、特定のカラムが極端に偏ったデータ(「A」が9割で「B」が1割、みたいなケース)を持っている場合、デフォルトのサンプリングでは「B」の存在を見落とすことがある。その結果、オプティマイザが「Bはほとんどないはずだ」と判断を誤り、フルスキャンを選択して爆死する……なんてのは、よくある悲劇だ。

そういう時は、特定のカラムだけターゲットを引き上げてやろう。

— 特定のカラムだけ統計精度を上げる(最大1000まで)
ALTER TABLE orders ALTER COLUMN status SET STATISTICS 500;

こうすることで、テーブル全体の設定はいじらずに、重要なカラムだけピンポイントで精度を担保できる。これ、かなり使えるテクニックだよ。

—

注意点:統計情報収集の「時間」と「精度」のトレードオフ

実務で一番怖いのは、「統計情報が古くて実行計画がバグる」ことと、「統計情報収集が重すぎて本番に影響が出る」ことの板挟みだ。

大規模なテーブルに対して「よし、精度を上げよう!」と全カラムの `STATISTICS` を `1000` に上げると、`ANALYZE` の実行時間が数倍に跳ね上がる。本番環境の負荷を考えたら、無闇に上げるのはNGだ。

おすすめの運用アプローチ

1. まずはデフォルトで様子を見る:ほとんどのケースはこれで十分だ。
2. 実行計画が怪しいクエリだけ特定する:`EXPLAIN ANALYZE` を実行して、「推定行数(rows)」と「実際の行数(actual rows)」の乖離を確認しよう。
3. 乖離が激しいカラムだけチューニングする:先ほど紹介した `ALTER TABLE … SET STATISTICS` を適用する。
4. それでもダメなら、インデックスやテーブル構成を見直す:統計の問題ではなく、物理的なデータ配置の問題かもしれないからね。

—

最後に:統計情報の「鮮度」も忘れずに

統計情報がどんなに正確でも、データが更新されまくっていたら意味がないよね。PostgreSQLの `autovacuum` が動いているか確認するのは基本中の基本だ。

大規模なバッチ処理で一気にデータを突っ込んだ直後は、必ず手動で `ANALYZE` を叩くクセをつけておこう。

— 大量更新の直後に実行
ANALYZE VERBOSE orders;

`VERBOSE` をつければ、どの程度のデータをサンプリングしたのか、どのくらい時間がかかったのかがログに出る。一度自分の環境で流してみて、「あ、これくらいの負荷なら許容範囲だな」という感覚を掴んでおくのが、優秀なエンジニアへの第一歩だ。

統計情報は、データベースの「目」だ。この目が曇らないようにケアしてあげるだけで、クエリは驚くほど速くなる。ぜひ、今日の仕事から意識してみてくれ。

それじゃ、また現場で!

コメント

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