「遅いクエリ」に立ち向かう君へ:EXPLAINの正しい読み方をマスターしよう
やあ。最近、データベースのパフォーマンスチューニングに悩んでるって聞いたよ。
現場で「なんかこのクエリ遅いんだよね」って言われたとき、君ならどうする?とりあえず `EXPLAIN` を叩いて、画面いっぱいに表示される謎の文字列を眺めて、結局よくわからず「インデックスを貼ってみるか…」と勘に頼る――そんな経験、一度はあるんじゃないかな。
でも、それじゃあ本当の意味で「データベースを操っている」とは言えない。今日は、PostgreSQLの強力な武器である `EXPLAIN` を、現場の先輩として、明日から君が即戦力として読み解けるように噛み砕いて解説するよ。
—
1. EXPLAINは「旅の計画書」だと思えばいい
まず、`EXPLAIN` はクエリを実行しない。これが重要なんだ。
データベースのプランナ(最適化エンジン)が、「このクエリを実行するなら、こういう手順でデータを拾うのが一番効率的かな」と考えた「脳内シミュレーション」を出力しているに過ぎない。
まずは一番シンプルな形から始めよう。
EXPLAIN SELECT FROM users WHERE status = ‘active’;
これを叩くと、こんな感じの結果が出るはずだ。
Seq Scan on users (cost=0.00..15.20 rows=520 width=120)
Filter: (status = ‘active’)
ここで注目してほしいのは3つだけ。
- Seq Scan (シーケンシャルスキャン): テーブルを全件舐めてるってこと。「インデックスが効いていない」証拠だね。
- cost: 内部的なコスト指標。「最初の行を見つけるまでのコスト」と「全行処理するまでのコスト」のペアだ。相対的な数値だから、これの大小を比較するのが大事。
- rows: プランナが「これくらいの行数が返ってくるだろう」と予測した数。ここが実際のデータと大幅にズレていると、プランナは間違った判断(誤った結合順序など)をしがちだ。
—
2. 実践編:analyzeをつけて「現実」を突きつけよう
ただの `EXPLAIN` だけだと、あくまで「予測」だ。実務で本当に知りたいのは「実際にどこで時間がかかったのか」だよね。そこで登場するのが `EXPLAIN (ANALYZE, BUFFERS)` だ。
EXPLAIN (ANALYZE, BUFFERS) SELECT FROM orders WHERE user_id = 12345;
`ANALYZE` をつけると、実際にクエリを実行して計測してくれる。`BUFFERS` をつけると、メモリ(Shared Hit)とディスク(Read)からそれぞれどれくらいデータを読み込んだかが分かる。
- Actual Time: 実際にかかったミリ秒だ。ここで「どこがボトルネックか」を一発で見抜く。
- Buffers: ここが一番大事!`Read` が多いクエリは、ディスクI/Oが発生していて遅いということ。`Hit` が多ければメモリ上で処理できているから、基本的には速い。
もし君が「クエリが遅い」という相談を受けたら、迷わずこのコマンドを打って、`Read` が発生している箇所を探してごらん。そこが君のメスを入れるべきポイントだよ。
—
3. 先輩からのワンポイントアドバイス
最後に、現場で役立つちょっとしたコツを伝授しておくね。
1. 「コスト」よりも「ステップ」を見る:
コストの数値自体に一喜一憂しないでほしい。大事なのは、「なぜこの結合順序になったのか?」「なぜこのインデックスが使われなかったのか?」という実行手順(プラン)の流れだ。
2. `EXPLAIN (FORMAT JSON)` を活用せよ:
複雑なクエリになると、出力が長すぎて目が滑る。そんなときは `(FORMAT JSON)` で出力して、「[explain.depesz.com](https://explain.depesz.com/)」のような可視化ツールにコピペしてみよう。視覚的にどこが重いか一目瞭然になるから、研修中の君には特におすすめだ。
3. 「早すぎる最適化」を避ける:
`EXPLAIN` を見て「お、ここをいじれば速くなりそう!」と思っても、いきなり本番環境で試すのは禁物だ。まずは検証環境で、統計情報(ANALYZEで更新される)が本番と同等であることを確認してからチューニングを始めてね。
—
まとめ
`EXPLAIN` は、データベースというブラックボックスの中身を可視化してくれる、最高の相棒だ。
最初は難しく見えるかもしれないけど、何度も叩いて、`Seq Scan` が `Index Scan` に変わる瞬間の快感を覚えてほしい。そうすれば、君はもう一段階上のエンジニアになれるはずだ。
さて、今日はここまでにしようか。もし特定のクエリで詰まったら、またいつでも相談してくれ。一緒に解析してやろう。
それじゃ、良い開発を!
コメント