このコマンドは PostgreSQL プランナが提供された問い合わせ文用に生成する実行計画を表示します。 この実行計画は、この文によって参照されるテーブル (複数の場合もあり) がスキャンされる方法 (単純なシーケンススキャン、インデックススキャン、など) を示したり、複数のテーブルが参照される場合にはそれぞれの入力テーブルに必要な行を組み合わすために使用される結合アルゴリズムを示したりします。
この表示で最も重要なのは、文の実行にかかるコストの見積もりです。 コストとは、プランナが推定する、文の実行にかかる時間 (ディスクページ抽出の単位で計測) です。 実際には 2 つの数が表示されます。 最初の行が返される前のスタートアップ時間、そして全ての行が返されるまでの合計の時間です。 ほとんどの問い合わせにとって問題となるのは合計時間ですが、EXISTS 副問い合わせなどのコンテキストでは、プランナは最も短い合計時間ではなく最も短いスタートアップ時間を選びます (エグゼキュータは行を 1 つ取得した後に停止するからです)。 更に、もし 句で返す行数を制限する場合、プランナはどの計画が一番低コストになるかを概算するため処理の終了までにでふさわしい書き換えを行ないます。
ANALYZE オプションにより、文は計画だけではなく実際に実行されます。 各計画ノードにて費やされた総経過時間(ミリ秒単位)と実際に返される行数が表示に追加されます。 プランナの推測と実際の値がどれだけ近いかを確認できるという点でこのオプションは有用なものです。
重要項目: ANALYZE を使用した場合は、文が実際に実行されることを忘れないで下さい。 EXPLAIN は SELECT が返すはずの出力を全く表示しませんが、文の副作用は通常通り発生します。 INSERT、UPDATE、DELETEEXECUTE 文に対して EXPLAIN ANALYZE をデータに影響が出ないように使用したい場合は、以下の方法を使用して下さい。
BEGIN; EXPLAIN ANALYZE ...; ROLLBACK;
コマンドを実行し、実際の稼働時間を表示します。
要約だけではなく計画ツリーの内部表現を全て表示します。 通常、このオプションは PostgreSQL のデバッグの際にのみ有用です。 VERBOSE の出力は、設定ファイルにおける explain_pretty_print の設定次第で印刷に適した形にすることもできます。
実行計画の表示対象となる、任意のSELECT, INSERT, UPDATE,DELETE, EXECUTE, もしくは DECLARE文です。
PostgreSQL のオプティマイザにおけるコスト情報の使用に関する文書は多くありません。 さらに詳しい情報については、項13.1を参照してください。
PostgreSQL問い合わせプランナが問い合わせの最適化の際に十分に情報を持った決定ができるようにするために、ANALYZE 文を実行して、テーブル内のデータの分布についての統計情報を記録させなければなりません。 これを行わない場合(、あるいは、前回ANALYZE を実行した後、テーブル内のデータの統計的分布が大幅に変わった時)、推定コストは、問い合わせの実際の属性とは適合することはなく、その結果、劣った問い合わせ計画が選択されることになります。
PostgreSQL の 7.3 より前のバージョンでは、問い合わせ計画は NOTICE メッセージという形式で通知されていました。 現在では、問い合わせ計画は問い合わせ結果 (単一のテキスト列から成るテーブルの形式で) として表示されます。
一つの integer 列と 10000 行を持つテーブル上の単純な問い合わせの問い合わせ計画を表示します。
EXPLAIN SELECT * FROM foo; QUERY PLAN --------------------------------------------------------- Seq Scan on foo (cost=0.00..155.00 rows=10000 width=4) (1 row)
インデックスがある場合、インデックス付けが可能な WHERE 条件を持つ問い合わせを使用すると、EXPLAIN は異なる計画を表示します。
EXPLAIN SELECT * FROM foo WHERE i = 4; QUERY PLAN -------------------------------------------------------------- Index Scan using fi on foo (cost=0.00..5.98 rows=1 width=4) Index Cond: (i = 4) (2 rows)
集約関数を使用した問い合わせに対する問い合わせ計画の例を示します。
EXPLAIN SELECT sum(i) FROM foo WHERE i < 10; QUERY PLAN --------------------------------------------------------------------- Aggregate (cost=23.93..23.93 rows=1 width=4) -> Index Scan using fi on foo (cost=0.00..23.92 rows=6 width=4) Index Cond: (i < 10) (3 rows)
以下は EXPLAIN EXECUTE を使用してプリペアードクエリに対する実行計画を表示する例です。
PREPARE query(int, int) AS SELECT sum(bar) FROM test WHERE id > $1 AND id < $2 GROUP BY foo; EXPLAIN ANALYZE EXECUTE query(100, 200); QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- HashAggregate (cost=39.53..39.53 rows=1 width=8) (actual time=0.66..0.67 rows=7 loops=1) -> Index Scan using test_pkey on test (cost=0.00..32.97 rows=1311 width=8) (actual time=0.05..0.39 rows=99 loops=1) Index Cond: ((id > $1) AND (id < $2)) Total runtime: 0.85 msec (4 rows)
もちろん、ここで示した具体的な数値は対象とするテーブルの実際の中身によって変わります。 また、この数値や選択された問い合わせ戦略は、プランナの改良のために PostgreSQL のリリース間で異なることもありますので注意してください。 更に、ANALYZE コマンドは、データの統計情報を推定する際にランダムなサンプリングを行いますので、実際のテーブル内の分布が変わっていなくても、新しくANALYZE を実行した後に推定コストが変わることがあります。