【実務・中級編】 統計情報収集 – PostgreSQL

「最近、本番環境のクエリが急に遅くなった気がするんだよね……」

現場でそんな相談を受けたとき、真っ先に僕がチェックするのは `EXPLAIN ANALYZE` の結果と、それに続く「統計情報の鮮度」です。

PostgreSQLは非常に賢いデータベースですが、彼が正しい判断を下すためには、テーブルの中身がどうなっているかという「地図」が必要です。それが今回話す「統計情報(Statistics)」です。

これが古くなっていると、プランナは「10件しかない」と踏んでいたテーブルに対して、実際には「100万件」のデータがあることを知らずに、悲惨なフルスキャンを選択してしまったりします。

今日は、現場で生き残るための「統計情報との付き合い方」について、少し踏み込んで話していこうと思います。

—

1. なぜ統計情報が「命綱」なのか

PostgreSQLのプランナは、クエリが投げられた瞬間に、どのインデックスを使い、どの順番で結合するのが一番速いかを計算します。このとき使われるのが `pg_statistic` というシステムカタログに格納された情報です。

  • 行数(n_tuples): テーブルに何行あるか。
  • 頻度(most_common_vals): どの値がどれくらい出現するか。
  • 相関(correlation): 物理的な並び順とインデックスの順序がどれくらい一致しているか。

これらがズレていると、プランナは「勘違い」を起こします。特に、大量のデータをバッチ処理で挿入・削除した直後は要注意。オートバキュームが追いついていないと、プランナの脳内には「古い過去のデータ」しか存在しない状態になるからです。

2. まずは現状を確認する癖をつけよう

「なんか遅いな」と思ったら、まずは対象テーブルの統計情報がいつ更新されたかを見てみましょう。

SELECT relname, last_analyze, last_autoanalyze
FROM pg_stat_user_tables
WHERE relname = ‘your_target_table’;

`last_autoanalyze` が何日も前だったり、そもそも NULL だったりしたら、それが原因の可能性が高いです。

3. 実践:統計情報を手動で「強制的」に更新する

オートバキュームを待つのが基本ですが、本番環境でのデプロイ直後や、数千万件のデータを一気に流し込んだ直後は、待っていられませんよね。そんな時は、迷わず手動で `ANALYZE` を打ちます。

— 特定のテーブルだけサクッと更新
ANALYZE your_target_table;

— データベース全体を更新(重いので運用時は注意!)
ANALYZE VERBOSE;

ここで一つテクニック。`ANALYZE` を実行すると、PostgreSQLはテーブル全体をスキャンするのではなく、「適当にサンプリング」して情報を推定します。このサンプリング精度を調整するのが `default_statistics_target` です。

通常は `100` ですが、特定カラムのデータの偏りが激しく、プランナがどうしても誤判定してしまう場合は、カラム単位で精度を上げることができます。

— このカラムだけは超慎重に統計を取ってくれ!
ALTER TABLE your_target_table ALTER COLUMN user_id SET STATISTICS 500;
ANALYZE your_target_table;

※数値を大きくすれば精度は上がりますが、分析にかかる時間も増えるので、むやみに大きくするのは禁物ですよ。

4. 現場でよくある「落とし穴」

僕が以前遭遇したトラブルに、「一時テーブル」の問題があります。

一時テーブルはセッション終了とともに消えますが、大量に生成・破棄される環境だと、オートバキュームがうまく機能せず、統計情報がめちゃくちゃになることがあります。

もし、一時テーブルを多用する複雑なクエリがあるなら、処理の途中で明示的に `ANALYZE` を呼ぶだけで、実行時間が秒単位で短縮されることがよくあります。

最後に:統計情報は「生き物」だと思って接する

エンジニアとして覚えておいてほしいのは、「完璧な統計情報なんて存在しない」ということです。データは常に増え、偏り、形を変えます。

だからこそ、クエリが遅くなったときに「インデックスが足りないのかな?」と悩む前に、「そもそも今の統計情報は現実と合っているのか?」と疑う視点を持ってください。

まずは `pg_stat_user_tables` を覗くこと。これが、熟練DBエンジニアへの第一歩です。

明日からの運用で、ぜひ活用してみてください。また何か詰まったら、いつでも聞きに来てね。

コメント

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