【実務・中級編】 EXPLAIN ANALYZE – PostgreSQL

「遅いクエリ」に立ち向かう君へ。EXPLAIN ANALYZEは怖くない!

現場で働いていると、必ず一度は遭遇するよね。「さっきまでサクサク動いていたはずの検索画面が、急に重くなった」とか、「数万件のデータでこのレスポンスはさすがにマズい」といったトラブル。

そんな時、とりあえず `SELECT FROM …` を眺めて悩むのはもう終わりにしよう。PostgreSQLには、「なぜそのクエリが遅いのか」を白日の下に晒す最強の武器がある。それが `EXPLAIN ANALYZE` だ。

今日は、僕が実務でどうやってこのツールと付き合っているか、その「現場の勘所」を伝授するよ。

—

EXPLAIN ANALYZE って結局なんなの?

一言で言うと、「クエリの健康診断」だ。

ただの `EXPLAIN` は「どう動く予定か」という計画書を出すだけ。でも、`EXPLAIN ANALYZE` は実際にクエリを実行して、「計画と現実にどれくらいのギャップがあったか」まで教えてくれる。

大事なのは、「計画(見積もり)と現実(実績)のズレ」を見つけること。これがチューニングの第一歩なんだ。

実践!こんな風に使ってみよう

例えば、ユーザーのアクセスログを検索するこんなクエリが遅いとするよ。

EXPLAIN (ANALYZE, BUFFERS)
SELECT FROM access_logs
WHERE user_id = 12345
AND created_at > ‘2023-01-01’;

ここで一つコツ。`BUFFERS` オプションを必ず付けること。「ディスクから読んだのか、メモリ(キャッシュ)から読んだのか」が分かるだけで、問題の深刻さが全然違って見えるからね。

結果が返ってきたら、特に以下のポイントをチェックするんだ。

  • actual time: 実際に何ミリ秒かかったか。
  • rows: 実際に何行ヒットしたか。
  • loops: 何回その処理を繰り返したか(ここが予想より多いと要注意)。
  • Shared Hit/Read: キャッシュヒット率の指標。ここが多いとI/O負荷が高い証拠。

「あれ?計画と違うぞ?」がチューニングのサイン

よくある「罠」がこれだ。

PostgreSQLのオプティマイザは、テーブルの統計情報をもとに「この検索ならインデックスを使うのが速いな」と判断する。でも、統計情報が古かったり、データが偏っていたりすると、「全件スキャン(Sequential Scan)したほうがマシ」という誤った判断を下すことがある。

もし `EXPLAIN ANALYZE` の結果で、本来インデックスが効くはずの場所で `Seq Scan` が走っていたら、まずは `ANALYZE` コマンドを叩いて統計情報を更新してみよう。これだけで解決することも案外多いんだ。

それでも直らないなら、インデックスの設計を見直すタイミングだね。

現場で気をつけるべき「注意点」

これだけは絶対に忘れないでほしい。

「`EXPLAIN ANALYZE` はクエリを実際に実行する」ということ。

つまり、`UPDATE` や `DELETE` 文に `ANALYZE` を付けたら、本当にデータが書き換わってしまう。 これをやって青ざめたエンジニアを何人も見てきたよ。本番環境で実行する時は、必ず `BEGIN;` でトランザクションを張ってから実行して、最後に `ROLLBACK;` する癖をつけておこう。

最後に:道具に振り回されないために

`EXPLAIN ANALYZE` の結果は、最初は呪文のように見えるかもしれない。でも、何度も見ていると「あ、ここはループが多すぎるな」「結合の順序が不自然だな」と、直感的にわかるようになる。

ツールはあくまで補助輪だ。一番大事なのは、「データがどう格納され、どう検索されるのが理想か」を想像する力だよ。

もしクエリの実行計画で詰まったら、いつでも相談してくれ。一緒にコードを読み解こう。君が書いたクエリが、明日から少しでも速く、美しく動くことを願っているよ!

コメント

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