【実務・中級編】 EXPLAINオプション – PostgreSQL

「EXPLAINだけで満足してない?」PostgreSQLの実行計画を解像度高く読み解く技術

現場で「クエリが遅い」って相談を受けたとき、真っ先に `EXPLAIN` を叩くよね。もちろんそれは正解。でも、ただの `EXPLAIN` だけだと、実は情報の「氷山の一角」しか見えていないって気づいてた?

PostgreSQLには、実行計画の「裏側」を覗き見るための強力なオプションがいくつも用意されているんだ。今日は、パフォーマンスチューニングの現場で僕が必ずと言っていいほど使っている、実践的なオプションたちを紹介するよ。

—

1. まずは基本の「三種の神器」:BUFFERS, ANALYZE, TIMING

クエリのチューニングにおいて、一番の敵は「I/O」だ。メモリ上で完結するのか、それともわざわざディスクまでデータを取りに行っているのか。これを知るために `BUFFERS` は必須。

EXPLAIN (ANALYZE, BUFFERS)
SELECT FROM users WHERE last_login > ‘2023-01-01’;

これを実行すると、`Shared Hit`(メモリヒット)と `Shared Read`(ディスク読み込み)が数値で見えるようになる。「え、なんでこのインデックススキャンでディスク読み込みが発生してるの?」といった違和感に気づけるのは、このオプションのおかげだね。

あ、ちなみに `ANALYZE` をつけると実際にクエリが実行されるから、UPDATEやDELETEで使うときは細心の注意を払ってね。あと、もし計測のオーバーヘッドすら削りたい繊細なケースなら `TIMING OFF` を検討してもいいけど、基本は `TIMING ON` で大丈夫だよ。

—

2. 「設定値」が犯人だった!:SETTINGS

「開発環境では速いのに、本番だとプランが変わる」。これ、エンジニアを絶望させるあるあるだよね。原因の多くは `work_mem` や `random_page_cost` といったパラメータの違いにある。

そんなとき、いちいち設定ファイルを見に行く必要はない。`SETTINGS` オプションを使えばいいんだ。

EXPLAIN (ANALYZE, SETTINGS)
SELECT FROM orders ORDER BY created_at DESC LIMIT 10;

こうすると、実行計画の最後の方に、実行時のパラメータ設定がズラッと表示される。「あ、本番だけ `work_mem` が小さくて外部ソートが発生してたのか!」なんてことが一目でわかる。これを知ってると、調査時間が劇的に短縮されるよ。

—

3. 深淵を覗く:VERBOSE

`VERBOSE` は、実行計画の出力に「カラムの詳細」や「プランナーがどんな計算をしているか」という情報を付け足してくれるオプションだ。

特にJOINの条件や、カラムの出力情報が曖昧なときに役立つ。例えば、「このテーブル、どのカラムを何のために参照してるんだっけ?」といった疑問が湧いたとき、`VERBOSE` をつければ `Output` フィールドが見えるようになる。

EXPLAIN (VERBOSE)
SELECT u.name, o.amount FROM users u JOIN orders o ON u.id = o.user_id;

大規模なJOINが絡む複雑なクエリを追うとき、情報の解像度を上げるための「顕微鏡」だと思っておいて。

—

4. 隠れたコストを可視化する:WAL

最近のPostgreSQLのチューニングで意外と見落とされがちなのが「WAL(Write Ahead Log)の書き込み量」。大量のデータを書き換えるバッチ処理なんかでは、実はCPUよりもWALへの書き込みがボトルネックになっていることが多いんだ。

EXPLAIN (ANALYZE, WAL)
UPDATE users SET status = ‘active’ WHERE status = ‘pending’;

これを確認することで、「このクエリ、どれくらいのログを吐き出しているのか」がわかる。WALの生成量が異常に多いなら、インデックスを減らすとか、一度に更新する行数を絞るといった戦略が見えてくるはずだよ。

—

まとめ:道具を使いこなして「勘」を「確信」に変えよう

駆け出しの頃の僕は、`EXPLAIN` の結果を眺めて「なんとなく遅そうだな」という直感でインデックスを貼っていた。でも、それだと運用が長くなるにつれて必ず限界が来る。

今回紹介したオプションは、いわばエンジニアの「聴診器」だ。

  • BUFFERS: I/Oの健康状態を知る
  • SETTINGS: 環境の差異を特定する
  • VERBOSE: 処理の細部を覗き込む
  • WAL: 書き込み負荷を測定する

これらを組み合わせることで、クエリの挙動を論理的に説明できるようになる。そうすれば、同僚やマネージャーに対しても「なぜその修正が必要なのか」を自信を持って伝えられるようになるはずだ。

次はぜひ、手元の重たいクエリで試してみてほしい。きっと、今まで見えなかった「ボトルネックの正体」が浮かび上がってくるから。また現場で何か詰まったら、いつでも聞いてくれよな!

コメント

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