なぜPostgreSQLは「勘違い」をしてしまうのか?:統計情報の不思議な世界
こんにちは!データベースの世界にどっぷり浸かっているエンジニアです。
皆さんは、PostgreSQLを使っていて「さっきまで爆速だったクエリが、急に遅くなった……」なんて経験はありませんか?インデックスも貼っているし、SQLも間違っていないはずなのに。
実はそれ、データベースの「頭脳」であるプランナが、今のデータの状況を正しく把握できていないからかもしれません。
今日は、そんなPostgreSQLの「勘違い」を防ぐための、とっても大事な「統計情報」と「ANALYZE」について、専門用語を抜きにしてお話ししますね。
—
「料理のレシピ」と「冷蔵庫の中身」
データベースがSQLを実行するとき、裏側では「どうやってデータを検索するか」という計画(実行計画)を立てています。これは例えるなら、料理を作るときの「レシピ」のようなものです。
しかし、ここで問題が起きます。プランナは、「冷蔵庫の中に何がどれくらい入っているか」を完璧には把握していないんです。
- 「玉ねぎは1個だけだと思っていたら、実は100個あった」
- 「もう売り切れたと思っていた食材が、実は山積みだった」
こんなふうに、手元の在庫(データ)が変わっているのに、古いメモ帳を見て計画を立ててしまったら、どうなるでしょう?「玉ねぎ1個だと思って手作業で刻み始めたら、実は100個あって日が暮れた」なんてことになりますよね。
これが、クエリが遅くなる原因の正体です。
—
「ANALYZE」という名の棚卸し
この「冷蔵庫の在庫状況(統計情報)」を最新の状態にアップデートしてくれる魔法のコマンドが、`ANALYZE` です。
`ANALYZE`を実行すると、PostgreSQLはテーブルの中身をチラッと覗き見して、「お、今はデータが100万件に増えてるな」「このカラムには『東京』というデータが異常に多いな」といった傾向をメモ帳に書き込みます。
これさえあれば、プランナは「あ、データが多いなら、全部読むよりもインデックスを使ったほうが早そうだな!」と、賢い判断ができるようになるわけです。
—
自動でやってくれるから大丈夫……?
「でも、PostgreSQLには自動でやってくれる機能(Autovacuum)があるよね?」と思ったあなた、鋭いですね!その通りです。
通常、PostgreSQLはデータの変更が一定量溜まると、勝手に`ANALYZE`を走らせてくれます。でも、これには少しだけ「時差」があるんです。
- 大量のデータを一気に流し込んだ直後
- データの傾向がガラッと変わった直後
こういうタイミングでは、自動実行を待たずに、人間が手動で `ANALYZE テーブル名;` と声をかけてあげるのが、実は一番の特効薬なんです。
—
今日のまとめ:データベースを「信頼できるパートナー」にするために
最後に、これだけ覚えておいてください。
1. 統計情報は、プランナにとっての「現在の地図」である。
2. 地図が古いと、どんなに優れたプランナでも道に迷う。
3. 「なんか遅いな?」と思ったら、まずは`ANALYZE`で最新の状況を教えてあげよう。
データベースは、私たちが適切に情報を提供してあげれば、期待以上のパフォーマンスで応えてくれる素晴らしい相棒です。ぜひ皆さんの環境でも、「最近、統計情報を見直したかな?」と気にしてみてくださいね。
それでは、また次回の記事でお会いしましょう!質問があれば、いつでもコメント欄に書き込んでくださいね。
コメント