【実務・中級編】 相関統計情報 – PostgreSQL

「なぜかプランナが罠にハマる…」そんな時は PostgreSQL の「相関統計情報」を疑え!

やあ。PostgreSQLのパフォーマンスチューニングで頭を抱えている君、お疲れ様。

クエリが遅い原因の8割は「実行計画(EXPLAIN)のミス」だよね。特に、複数の条件を組み合わせた時に、PostgreSQLが「おいおい、そんなにデータ戻ってくるわけないだろ!」っていう予測をして、インデックスを使わずにフルスキャンを選択してしまう……あの絶望的な瞬間。

あれ、実は「カラム間の相関」をPostgreSQLが読み取れていないだけのことが多いんだ。今日は、そんな時に魔法のように効く「拡張統計情報(Extended Statistics)」の話をしよう。

—

なぜ PostgreSQL は「嘘」をつくのか?

まず、基本のおさらいだ。PostgreSQLのプランナは、テーブルの統計情報を使って「この条件なら何行ヒットするか」を計算する。

例えば、こんなテーブルがあるとする。

  • `prefecture_code`(都道府県コード)
  • `city_name`(市区町村名)

ここで君がこんなクエリを投げたとしよう。

SELECT FROM addresses
WHERE prefecture_code = ’13’ AND city_name = ‘世田谷区’;

PostgreSQLの標準的な統計情報は、各カラムを「独立したもの」として扱う。つまり、「`prefecture_code = 13` である確率」と「`city_name = 世田谷区` である確率」をそれぞれ計算して、単純に掛け算してしまうんだ。

でも現実には、`city_name` が『世田谷区』なら、ほぼ確実に `prefecture_code` は『13(東京都)』だよね。この相関関係をプランナは知らないから、実際には数千件しかない結果を「数百万件あるはずだ!」と見積もりミスをして、わざわざ重いシーケンシャルスキャンを選んでしまうわけ。

—

「拡張統計情報」という切り札

そんな時こそ、PostgreSQL 10以降から強化された「拡張統計情報」の出番だ。これを使うと、カラム間の相関関係を明示的に学習させることができる。

使い方は驚くほど簡単。`CREATE STATISTICS` コマンドを打つだけだ。

CREATE STATISTICS stat_pref_city
ON prefecture_code, city_name
FROM addresses;

— 統計情報を更新(ANALYZE必須!)
ANALYZE addresses;

これだけで、PostgreSQLは「この2つのカラムの間には強い相関があるぞ」と認識してくれるようになる。次に `EXPLAIN` を叩いてみてほしい。見積もり行数(rows)が、実際の行数にグッと近づいているはずだ。

—

どんな時に使うべきか?(現場の勘所)

ただ、何でもかんでも統計を作ればいいというわけじゃない。統計情報を増やすと、その分 `ANALYZE` の負荷も上がるし、カタログも肥大化する。僕が現場で「ここは統計を作っておくべき」と判断するのはこんなケースだ。

1. WHERE句で「あるカラムAが決まればカラムBも決まる」関係が頻出する場合

  • 都道府県と市区町村、郵便番号と住所、カテゴリIDとサブカテゴリIDなど。

2. 実行計画が不安定で、たまに異常に遅いクエリがある場合

  • 特に、結合(JOIN)の順序が日によって変わったりするようなケース。

3. データ量が多い大規模テーブル

  • 見積もりが10倍外れるだけで、Nested Loopを避けてハッシュ結合を選んだり、逆にその逆をやったりと、クエリの実行効率が劇的に変わるからね。

—

注意点:魔法じゃない、あくまで「支援」

一つだけ忠告しておこう。拡張統計情報は、あくまで「プランナに正しいヒントを与える」ためのものだ。

もし、カラム間の相関を正してもまだ遅いなら、それはインデックスの設計自体が間違っているか、クエリの書き方が悪い可能性が高い。 統計情報に逃げる前に、まずは `EXPLAIN (ANALYZE, BUFFERS)` を見て、どこで本当に時間がかかっているかを見極める癖をつけてほしい。

「統計情報で解決できるはず」と決めつけて深追いしすぎると、かえって落とし穴にハマる。DBエンジニアとして、常に「事実」と「見積もり」を切り分けて考えるのが、一流への近道だよ。

—

まとめ:今日からできること

1. 今のクエリの実行計画で、`rows` と `actual rows` に大きな乖離がないか確認する。
2. 乖離があるカラム同士が、論理的に相関していないか考える。
3. `CREATE STATISTICS` を試し、`ANALYZE` して実行計画の変化を確認する。

もし「やってみたけど変わらないぞ?」ということがあれば、いつでも相談してくれ。データベースの世界は奥が深い。その分、少しの知識で劇的に速くなる瞬間が最高に面白いんだ。

じゃあ、また現場で会おう。健闘を祈る!

コメント

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