【テクニカル・上級編】 プランナメソッド設定 – PostgreSQL

禁断の果実:PostgreSQLの「プランナメソッド設定」とどう向き合うべきか

PostgreSQLの運用にどっぷり浸かっていると、一度は必ず「なぜオプティマイザはこの鈍重なシーケンシャルスキャンを選んだんだ?」と天を仰ぐ夜があるはずです。インデックスは完璧に張ってある。統計情報も最新。それなのに、あえて全表走査を選ぶプランナ。

そんな時、目の前に現れるのが `enable_seqscan` や `enable_indexscan` といった、いわゆる「プランナメソッド設定」です。

これらは、PostgreSQLという強大なエンジンに対して、私たちが直接「こう動け」と命令を下すためのパラメータ群です。しかし、これらは諸刃の剣。エンジニアとして、この「禁断の果実」をいつ、どのように使うべきか。今日はその核心に踏み込んでみたいと思います。

—

なぜ、プランナは「間違える」のか

まず大前提として、プランナは意地悪で間違ったプランを出しているわけではありません。それは、彼が持っている「統計情報」という名の地図と、コスト見積もりのモデルが、現実のデータ分布や計算資源の状況と微妙にズレているだけなのです。

`enable_seqscan = off` を実行して、無理やりインデックススキャンを強制したくなる気持ちは痛いほど分かります。しかし、それをやる前に一度立ち止まりましょう。

プランナがシーケンシャルスキャンを選ぶ理由は、多くの場合「コストモデル」にあります。大量のデータをインデックス経由で読み取ると、ランダムI/Oが多発し、結果としてシーケンシャルにメモリへ流し込むよりも負荷が高いと判断されているのです。つまり、「インデックス=速い」というのは、あくまで特定の条件下での仮説に過ぎません。

メソッド設定を「本番で」使うことの危うさ

`enable_…` 系パラメータを本番環境で恒久的に設定するのは、私から言わせれば「爆弾を抱えて寝る」のに等しい行為です。

1. 環境の変化に追従できなくなる:
テーブルの肥大化やデータの偏り(スキュー)が発生した際、当初は最適だったはずのインデックススキャンが、突然「遅すぎて使い物にならない」プランに変わる可能性があります。しかし、その時プランナは他の選択肢を「禁止」されているため、最悪の実行計画を盲目的に実行し続けます。
2. プランキャッシュの罠:
セッション単位で一時的に変更する場合でも、コネクションプーラーを使っている環境では、その設定が意図せぬクエリに漏れ出すリスクがあります。

正しいトラブルシューティングの作法

では、クエリが遅いとき、私たちはどうすべきか。私はいつも、プランナメソッド設定を「武器」ではなく「診断ツール」として使うことを推奨しています。

  • STEP 1: 比較検証

`set enable_seqscan = off;` を実行した状態と、そうでない状態で `EXPLAIN ANALYZE` を叩き、実行時間とコストを比較します。

  • STEP 2: なぜ選ばれなかったのかを探る

`EXPLAIN (ANALYZE, BUFFERS)` を見てください。読み込んでいるブロック数、期待される行数(rows)と実際の行数(actual rows)に乖離はありませんか?もし乖離があるなら、それはプランナのせいではなく、統計情報の収集不足(`ANALYZE` が足りない)や、カラム間の相関関係をプランナが理解できていないことが原因です。

  • STEP 3: 統計情報の改善とインデックスの再考

`CREATE STATISTICS` を使って相関関係をプランナに教える、あるいは `pg_stat_user_indexes` を確認して、本当にそのインデックスが適しているのかを再考する。ここがエンジニアの腕の見せ所です。

それでも「強制」が必要な時

もちろん、統計情報だけで解決できないエッジケースは存在します。極めて複雑な結合条件や、オプティマイザの限界を超えるような特殊なクエリです。

どうしても特定のプランを強制しなければならない時は、グローバルな設定を変えるのではなく、「特定のクエリに対してのみ」、あるいは 「そのセッション内でのみ」 適用するよう徹底してください。

BEGIN;
SET LOCAL enable_seqscan = off;
— ここで問題のクエリを実行
EXPLAIN ANALYZE SELECT …;
ROLLBACK;

このように、あくまで「分析のための切り分け」に留めるのが、熟練者の作法です。

—

最後に

PostgreSQLのプランナは、数十年かけて進化してきた知性の結晶です。彼らが選んだプランを否定する前に、「なぜ、彼はこのプランを選んだのか?」「彼に見えていて、私に見えていない事実は何か?」と問いかけてみてください。

プランナメソッド設定を封印し、統計情報やクエリの書き方を調整することで問題を解決できたとき、あなたのデータベースエンジニアとしての視座は、間違いなく一段高まっているはずです。

データベースは、エンジニアの問いかけに対して必ず正しく答えてくれます。その対話を、ぜひ楽しんでください。

コメント

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