by Hayato Matsuura

実行計画の作成


PostgreSQLの実行計画は、SQL文の前にexplainを置く事によって取得できます。しかし、1つ重要な制限事項があります。 バインドパラメータを使ったSQL文 ($1$2など)においては、この方法では実行計画を取得できません。まず最初にプリペアド ステートメントとして宣言する必要があるのです。

PREPARE stmt(int) AS SELECT $1

PostgreSQLでは、バインドパラメータに「$n」を使用する事に 注意しましょう。使用しているデータベース抽象化層によってはこれを隠してしまう事があるので、SQL標準で定義されているように、 クエスチョンマークを使いましょう。

プリペアドステートメントは以下のように実行します。

EXPLAIN EXECUTE stmt(1)

PostgreSQL 9.2以降では、実行時まで実行計画の作成は先送りされるので、バインドパラメータに関しては実際の値を考慮に入れます。バインドパラメータの実際の値を考慮しない実行計画を取得するため、PostgreSQL 16ではexplaingeneric_planオプションが導入されました。

注記

バインドパラメータなしの文に関しては、もっと単純な説明になります。

EXPLAIN SELECT 1

この時、オプティマイザはクエリの計画時に実際の値をいつも考慮に入れます。

実行計画の出力は次のようになります。

                QUERY PLAN                
------------------------------------------
 Result  (cost=0.00..0.01 rows=1 width=0)

出力は、この本で取り上げているOracleの実行計画とほぼ同じです。 処理名(「Result」)、関連するコスト値、行数の見積、行の長さです。

PostgreSQLは2つのコスト値を表示するのに注意しましょう。 1つ目は初期処理のコスト、2つ目は全行を取り出し終えるまでの処理の全コストです。 Oracleの実行計画では、2つ目の値しか表示されていません。

PostgreSQLのexplainコマンドには、analyzebufferssettingsといった非常に便利なものを含む多くのオプションがあります。

協力してください

この記事が気に入ったら、私の書いた本「SQLパフォーマンス詳解」や私によるトレーニングもきっと気にいるはず。

analyzeオプションを有効にすると、実行計画が作成されるだけでなく文の実行も行われます。これはつまり、delete文の情報を表示したい時に実際に削除が実行されてしまうといったように、情報を表示したい文を実行する際の副作用が発生しまうということです。このような副作用の影響が残らないようにしたい場合は、explainをトランザクションに入れて、実行後にロールバックすることもできます。

警告

explain analyzeは、対象が insertupdatedeleteの場合でも文を実際に実行してしまいます。

実際に文を実行することで、各処理における実行時間や、生成される行の実際の数といった実行時の情報を収集できます。またbuffersオプションは、アクセスされるデータベースブロック数を数えます。

最後にsettingsオプションは、デフォルト値から変わっている設定を表示します。

BEGIN
EXPLAIN (ANALYZE, BUFFERS, SETTINGS) EXECUTE stmt(1)
                   QUERY PLAN
--------------------------------------------------
 Result  (cost=0.00..0.01 rows=1 width=4)
         (actual time=0.001..0.002 rows=1 loops=1)
 Settings: random_page_cost = '1.1'
 Planning Time: 0.032 ms
 Execution Time: 0.078 ms
ROLLBACK

この表示はページに合うようにフォーマットしてあります。実際には「actual」の値は見積値と同じ行に表示されます。

行数は見積と実際の値、どちらの部分にも表示されています。 これによって、カーディナリティの見積のおかしな部分をすぐに見つけられます。

最後に大事な事ですが、プリペアドステートメントはクローズしておきましょう。

DEALLOCATE stmt
前へ次へ

You can’t learn everything in one day. Subscribe the newsletter via E-Mail, Bluesky or RSS to gradually catch up. Have a look at modern-⁠sql.com as well.

著者について

Markus Winandの写真

Markus Winand氏は、開発者がSQLパフォーマンスを改善するお手伝いをしています。彼は、SQL Performance Explainedの 著者でもあり、出張トレーニングhttp://winand.at/での リモート講義も 行っています。

彼の本

カバー『SQLパフォーマンス詳解』

核心をわかりやすく 解説。

Markusから購入します
(送料無料+PDF)

Amazon.co.jpで購入
(印刷版のみ)

Connect with Markus Winand

Markus Winand MailinglistsSubscribe RSS feedMarkus Winand on LinkedInMarkus Winand on XINGMarkus Winand on TwitterMarkus Winand on Bluesky
Copyright 2015-2025 Hayato Matsuura, Markus Winand. All righs reserved.
法律上の通知 | お問い合わせ | 無保証 | 商標 | プライバシーとGDPR