3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Postgres Explain Visualizer 2 を使って実行計画を可視化🐘👀

Last updated at Posted at 2025-12-24

はじめに

SQLチューニングにあたっては実行計画の分析が欠かせませんが、数行・十数行レベルの実行計画であればまだしも、数十行レベルの実行計画は読み解くだけで一苦労です。
そんな苦労を一部肩代わりしてくれるのが Postgres Explain Visualizer (以降、PEV2) です。
PEV2 はその名の通り実行計画 (実行統計) を可視化してくれるオープンソースのツールで、実行計画のみのインプットで見やすいツリー図を生成してくれるのに加え、ボトルネックとなってるステップが一目で分かるようになります。(SQLテキストのインプットは任意)

今回は、EXPLAIN時のオプションの違い等でツリー図がどう変化するかご紹介します。

前提

PostgreSQL のバージョンは V17、データは下記を参考にフライトデータ (大) を導入しました。

SQLはチャッピーに生成してもらった下記を使用しました。

WITH eligible AS (
  SELECT
    f.flight_id,
    f.flight_no,
    f.departure_airport,
    f.arrival_airport,
    f.aircraft_code,
    f.scheduled_departure,
    f.scheduled_arrival
  FROM
    bookings.flights AS f
  WHERE
    f.scheduled_departure >= '2017-01-01' :: timestamptz
    AND f.scheduled_departure < '2017-04-01' :: timestamptz
),
conn AS (
  SELECT
    f1.flight_id AS leg1_id,
    f2.flight_id AS leg2_id,
    f1.departure_airport AS origin,
    f1.arrival_airport AS hub,
    f2.arrival_airport AS dest,
    f1.aircraft_code AS ac1,
    (f2.scheduled_departure - f1.scheduled_arrival) AS layover
  FROM
    eligible AS f1
    JOIN eligible AS f2 ON f1.arrival_airport = f2.departure_airport
    AND f2.scheduled_departure BETWEEN f1.scheduled_arrival + INTERVAL '30 minutes'
    AND f1.scheduled_arrival + INTERVAL '6 hours'
    AND f1.departure_airport <> f2.arrival_airport
),
expanded AS (
  SELECT
    c.origin,
    c.hub,
    c.dest,
    c.layover,
    s1.seat_no
  FROM
    conn AS c
    JOIN bookings.seats AS s1 ON s1.aircraft_code = c.ac1
),
agg AS (
  SELECT
    origin,
    hub,
    dest,
    COUNT(*) AS weighted_connections,
    percentile_disc(0.5) WITHIN GROUP (
      ORDER BY
        layover
    ) AS p50_layover,
    percentile_disc(0.9) WITHIN GROUP (
      ORDER BY
        layover
    ) AS p90_layover
  FROM
    expanded
  GROUP BY
    origin,
    hub,
    dest
)
SELECT
  origin,
  hub,
  dest,
  weighted_connections,
  p50_layover,
  p90_layover
FROM
  agg
ORDER BY
  weighted_connections DESC
LIMIT
  100;

EXPLAIN

まずはEXPLAINのみの場合です。サイトには、

For best results, use EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)

と記載されていますが、テキスト形式でもツリー図を生成可能です。

コストが高いところ (今回は #5) にドルマーク ($) が表示されています。

image.png

詳しく知らないオペレーションがあっても、オペレーション名をクリックすると簡単な説明が表示されます。(マニュアルを確認しながら読む手間が省けます)

image.png

下記のリンクから、実際に生成したものをご覧いただけます。

EXPLAIN (ANALYZE)

次にANALYZEを指定した場合です。
EXPLAINのみの時と比較して、ぱっと見でもかなり情報が付加されていることがわかります。

時間を要しているステップには時計マーク (⏱) が表示されており、チューニングポイントが一目でわかるようになりました。(今回は #4, #5, #7)
また、行数の見積が不正確だったステップにはバッドマーク (👎)が表示されています。(今回は #3, #4, 他)
上位ステップへ返す件数に合わせて、ステップ間のリレーションが太く表示されるようになっています。

image.png

EXPLAIN (ANALYZE, BUFFERS)

BUFFERSを追加で指定すると、これまで左ペインで No data available と表示されていた箇所にも情報が表示されるようになりました。

image.png

image.png

EXPLAIN (ANALYZE, BUFFERS, VERBOSE)

VERBOSEを追加で指定すると、Statsタブなどで表示されるオブジェクト名にスキーマ名が表示されるようになります。

image.png

image.png

TRACK_IO_TIMING

TRACK_IO_TIMINGを ON にしたうえでEXPLAIN (ANALYZE, BUFFERS, VERBOSE)の結果をインプットすると、ディスクI/O に関する情報が表示されるようになりました。

image.png

image.png

ローカル実行

「実行計画とはいえ、インターネットにデータを流すのはちょっと…」という場合は、pev2.html を DL してローカル実行で使いましょう。pev2.html は github から DL できます。

image.png

image.png

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?