【入門編】 拡張統計情報(CREATE STATISTICS) – PostgreSQL

「なんでそんなに遅いの?」を解決する!PostgreSQLの隠し味『拡張統計情報』のお話

こんにちは!データベースの世界へようこそ。
日々PostgreSQLと向き合っていると、たまに「どうしてデータベース君は、そんなに効率の悪いルートを選んじゃうの?」と頭を抱えたくなるようなクエリに出会うこと、ありませんか?

「ちゃんとインデックスも貼っているし、条件も間違っていないはずなのに、なぜか検索が遅い……」

実はそれ、データベースが「勘違い」をしているのが原因かもしれません。今日は、そんなデータベースの勘違いを直して、クエリを爆速にするための魔法のスパイス『拡張統計情報(CREATE STATISTICS)』についてお話しします。

—

データベースは「優秀だけど、ちょっと天然」

データベースがクエリを実行するとき、必ず「どうやってデータを探せば一番早いかな?」という計画(実行計画)を立てます。でも、この計画を立てるとき、データベースは「統計情報」という、いわば「データの健康診断結果」のようなものを見ているんです。

ところが、この健康診断にはちょっとした弱点があります。それは、「列ごとの統計は詳しく見ているけれど、列同士の繋がりまでは見ていない」ということ。

これだと、ちょっと困ったことが起きます。例えば、こんなケースを想像してみてください。

  • テーブル: お洋服の在庫管理
  • 列A: 「ブランド名」
  • 列B: 「サイズ」

もしあなたが、「ユニクロ」かつ「XXLサイズ」の商品を探そうとしたとき、データベースはこう考えます。
「ユニクロの服はたくさんあるな(列Aの統計)。XXLサイズの服も世の中にはそこそこあるな(列Bの統計)。よし、この2つの条件を掛け合わせると、対象はこれくらいかな……?」

でも実際には、そのブランドは「小さいサイズしか作っていない」かもしれないですよね。列同士に深い関係がある場合、データベースの「別々に計算して掛け合わせる」という手法は、大きく的外れな結果を生んでしまうんです。

『拡張統計情報』は、二人の仲の良さを教えること

この「勘違い」を直すのが、`CREATE STATISTICS` です。
これは簡単に言うと、データベースに対して「この列とこの列は、こういう関係性があるんだよ!」と教えてあげることです。

例えるなら、仕事のチーム編成のようなもの。
「AさんとBさんは、いつもセットで行動するから、別々に予定を組むんじゃなくて、ペアとして考えてね」とマネージャー(データベース)に伝えてあげるんです。

そうすると、データベースは「おっと、そうだったのか!それならもっと効率的な近道があるね」と、今までとは全く違う、賢いルートを選択してくれるようになります。

どうやって使うの?

使い方は驚くほどシンプルです。例えば、`users` テーブルの `city`(都市)と `zip_code`(郵便番号)の間に強い相関があるなら、こんなふうにコマンドを打つだけです。

CREATE STATISTICS stats_city_zip ON city, zip_code FROM users;

これだけで、PostgreSQLは「あ、この2つの列はセットで見るといいのね」と学習してくれます。あとは、`ANALYZE` コマンドで統計情報を更新してあげるのを忘れずに。

最後に:魔法の使いすぎには注意!

ここまで読んで「じゃあ、全部の列に設定しちゃえ!」と思ったあなた、ちょっと待ってくださいね。

この機能は便利ですが、あまりにたくさん作りすぎると、今度は「統計情報を計算する作業」そのものがデータベースの負担になってしまいます。また、単純なテーブルや、全く関係のない列同士に設定しても意味がありません。

  • 「複数条件で絞り込むことが多いのに、なぜか実行計画が変だ」
  • 「特定の列同士の組み合わせが、結果の件数に大きく影響している」

そんな「ここぞ!」という場所にピンポイントで使ってあげるのが、一番の近道です。

データベースのチューニングは、まるで料理の味付けのようなもの。隠し味を上手に使って、あなたのクエリを最高のパフォーマンスに仕上げてみてくださいね。

それでは、また次回の記事でお会いしましょう!Happy Coding!

コメント

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