SQLの実行計画を読めるようになる(PostgreSQL)

SQLのパフォーマンスを測定するためのプラン(実行計画)について、「俺たちは雰囲気でプランを読んでいる」部分があって良くないと思ったので、ちゃんと読めるようになるため、情報を整理する。

explain と explain analyze

まず、プランを出させる方法について。

explain
  • 予想される実行計画を表示する
explain analyze
  • 実際にSQLを発行して、その時の実行計画を表示する
  • 実際にSQLを実行するので、レコードを変更するクエリやDBに負荷がかかりそうなクエリは注意

実行計画の読み方

actual time
  • 処理時間(ミリ秒)
cost
  • cost=0.00..18.00の形式で表示される
  • シーケンシャルな読み込み1回を1.00とした場合の相対値

  • 最初の数字は初期コスト(始動コスト)

    • 最初の行が返されるまでのコスト
    • 実行する前の事前準備がなければ0.00になる
  • 後の数字はトータルコスト(総コスト)

    • 最後の行が返されるまでのコスト
rows
  • 実行結果として返ってきた行数
width
  • データのサイズ
  • パフォーマンスを見るうえでそんなに重要じゃない
loops
  • ステップの実行回数
planning time
  • 解析されたクエリから実行計画を生成し、最適化するのに要した時間
execution time
  • 実行時間

で、結局どう見たらいいのか

  • explain analyzeで実際のプランを取得
  • トータルの時間が遅かったら、原因になっている箇所を探して改善方法を考える
    • Seq Scanになっててrowsが多い
      • インデックスの追加が必要なのか?
      • WHERE節を変えて既にあるインデックスを使えるようにできないか?
    • Index Scanだけどrowsがすごく多くてactual timeも長くなってる
      • 取得しなくていいレコードまで取得していないか? (= もっと条件を絞り込めないか)
        • たくさん絞り込める条件から先に実行されるように変えられないか? (WITHとか使って)
      • JOINするレコードを減らせないか?
        • 条件を増やして、JOINする前にレコード数を絞れないか?

こんな感じ?

参考にさせてもらったページ

qiita.com

www.slideshare.net