今回は、Goldの「G2 性能監視 - G2.3 クエリ実行計画」からの出題です。
postgres=# EXPLAIN SELECT relname,nspname FROM pg_class left join pg_namespace ON (pg_class.relnamespace = pg_namespace.oid);
QUERY PLAN
-------------------------------------------------------------------------
Hash Left Join (cost=1.14..15.97 rows=288 width=128)
Hash Cond: (pg_class.relnamespace = pg_namespace.oid)
-> Seq Scan on pg_class (cost=0.00..10.88 rows=288 width=68)
-> Hash (cost=1.06..1.06 rows=6 width=68)
-> Seq Scan on pg_namespace (cost=0.00..1.06 rows=6 width=68)
(5 行)
※この例題は実際のOSS-DB技術者認定試験とは異なります。
正解は「B」「D」「E」です。
ユーザやアプリケーションがデータベースに対してSQL文を実行させる際、
プランナによってSQL文を実行するための最適なアルゴリズムが自動的に選択され、
その後、エグゼキュータによって実際にSQL文が実行されるという流れになっています。
データベースを利用したアプリケーションの開発者にとっては、
より最適なアルゴリズムの選択をチューニングしたり、
同じ結果をもたらす複数のSQL構文の性能を評価したいケースがあります。
そのようなケースでは、EXPLAIN コマンドを利用することで、
SQL文を実際に実行せずにプランナーによるアルゴリズムの選択を確認し、評価することができます。
EXPLAINコマンドの実行の際の構文は以下の通りです。
(構文) EXPLAIN [ANALYZE] <SQL文>
例題のように、ANALYZE オプションをつけずに実行すると、<SQL文>は実際には実行されません。
一方、ANALYZE オプションをつけて実行すると、<SQL文>は実際に実行されます。
また、このような、EXPLAINコマンドの出力結果を、実行計画といいます。
実行計画は、SQL文が参照するテーブルのスキャンや、テーブル結合を行うアルゴリズムなどを示します。
実行計画の出力は以下のような構文になります。
QUERY PLAN
-------------------------------------------------------------------------
<計画ノード> (cost=<初期推定コスト>..<全体推定コスト> rows=<行数> width=<行の平均サイズ1>)
それぞれの項目の説明は以下の通りです。
<計画ノード>… ここには、エグゼキュータが実際にデータ処理するための具体的なアルゴリズムが記載されます。表スキャンや索引スキャン、表結合、ソートなど、さまざまなアルゴリズムがあります。
<初期推定コスト>… <計画ノード>に記載されたアルゴリズムによって最初の行を取得するまでの推定のコスト(時間)です。
<全体推定コスト>… <計画ノード>に記載されたアルゴリズムの処理が完了するまでの推定コスト(時間)です。
<行数>… 統計情報をもとに推測される処理行数です。
<行の平均サイズ>… 統計情報をもとに推測される、<計画ノード>の出力の1行あたりのバイト単位でのサイズです。
選択肢を一つずつ見ていきましょう。
[A. このEXPLAINコマンドを実行すると、引数に指定したSQL文が実際に実行される]
誤りです。例題のEXPLAINコマンドには、実際にSQLを実行するためのANALYZEオプションがついていませんので、SQLは実際に実行されません。
[B. 計画ノードの「Hash Left Join」、「Seq Scan on pg_class」、「Seq Scan on pg_namespace」の記述は、プランナが自動選択した最適なデータ処理のアルゴリズムを示している]
正しいです。
[C. 「cost=〜」の部分は、処理にかかる実際の時間を示している]
誤りです。costの部分は、処理を行う際の推定の初期コスト、全体コスト(時間単位)であり、実際にかかった時間を表示するものではありません。
[D. 「rows=〜」の部分は、それぞれの計画ノードを実行した際の推定の処理行数を示している]
正しいです。
[E. 「width=〜」の部分は、統計情報をもとに推測される1行あたりの平均のバイトサイズを示している]
正しいです。
今回の解説について、理解できないポイントがあればどんどん質問をお寄せ下さい。
※試験問題に関わるお問い合わせにつきましては、LPI-Japan事務局ではお応えできませんのでご了解ください。
© EDUCO All Rights Reserved.