SAK 図書館
SQL チューニング編3 - SQL 実行計画解析、EXPLAIN、ヒントオプション
Oracle 固有の部分があるかもしれません。SQL-Server、MDB では注意のこと。 ■表結合解析 ・表結合では、次のように NESTED LOOPS と、それぞれのテーブルに対する走査方法を解析できる。 表の結合においては、from 句の指定でレコード数の多いものから記述する 方が有利である。 (データベース最適化、データベースチューニング) truncate table plan_table; explain plan for select 受注番号, 受注m.品番 as 品番, 受注m.受注数 as 受注数, 品番m.受注数 as 受注累積, 受注m.得意先CD as 得意先CD, 得意先名, 受注m.更新担当者 as 更新担当者, 受注m.更新日付 as 更新日付, 受注m.更新時間 as 更新時間 from sak.受注m, sak.品番m, sak.得意先m where 受注m.品番 = 品番m.品番 (+) and 受注m.得意先CD = 得意先m.得意先CD (+) ; select operation || ' options= ' || options || ' object= ' || object_name || ' position= ' || position || ' cost= ' || cost from plan_table; 【SELECT STATEMENT options= object= position= cost= 【NESTED LOOPS options= OUTER object= position= 1 cost= 【NESTED LOOPS options= OUTER object= position= 1 cost= 【TABLE ACCESS options= FULL object= 受注M position= 1 cost= 【TABLE ACCESS options= BY INDEX ROWID object= 得意先M position= 2 cost= 【INDEX options= UNIQUE SCAN object= SYS_C00701 position= 1 cost= 【TABLE ACCESS options= BY INDEX ROWID object= 品番M position= 2 cost= 【INDEX options= UNIQUE SCAN object= SYS_C00699 position= 1 cost= ・表結合では、この他に MERGE JOIN SORT HASH JOIN (ハッシュ結合) がある。 次に説明するヒントオプションなどにより、検証できる。 ■ヒントオプション ・ヒントオプションでは、実行計画を明示的に指示できる。 /*+ FULL(受注m) */ - 全表走査する /*+ INDEX(受注m SYS_C00866) */ - 索引走査する /*+ PARALLEL(受注m, 8) */ - パラレル(多重度) を使用する /*+ RULE */ - 基本ルールベースにする /*+ ALL_ROWS */ - 表結合をもっとも良い方法にする /*+ FIRST_ROWS */ - 表結合の 1 レコードを一番速く返す ・例えば、受注m には、受注番号の索引があるので、次のように UNIQUE SCAN になる。 truncate table plan_table; explain plan for select * from sak.受注m where 受注番号 = '000001-001' ; select operation || ' options= ' || options || ' object= ' || object_name || ' position= ' || position || ' cost= ' || cost from plan_table; 【SELECT STATEMENT options= object= position= cost= 【TABLE ACCESS options= BY INDEX ROWID object= 受注M position= 1 cost= 【INDEX options= UNIQUE SCAN object= SYS_C00866 position= 1 cost= ・ヒントオプションで /*+ FULL(受注m) */ を指定すると、 FULL にできる。 ヒントオプションは、注釈記号の間に書く。 /* の後に余分な空白があってはならない。 またテーブル名にスキーマ修飾をしてはならない。 間違っていても単なる注釈と見なされるので注意する。 truncate table plan_table; explain plan for select /*+ FULL(受注m) */ * from sak.受注m where 受注番号 = '000001-001' ; select operation || ' options= ' || options || ' object= ' || object_name || ' position= ' || position || ' cost= ' || cost from plan_table; 【SELECT STATEMENT options= object= position= 1 cost= 1 【TABLE ACCESS options= FULL object= 受注M position= 1 cost= 1 ・ヒントオプションで /*+ INDEX(受注m SYS_C00866) */ を指定すると、 索引を使う実行計画を立てるように指示できる。 truncate table plan_table; explain plan for select /*+ INDEX(受注m SYS_C00866) */ * from sak.受注m where 受注番号 = '000001-001' ; select operation || ' options= ' || options || ' object= ' || object_name || ' position= ' || position || ' cost= ' || cost from plan_table; 【SELECT STATEMENT options= object= position= 1 cost= 1 【TABLE ACCESS options= BY INDEX ROWID object= 受注M position= 1 cost= 1 【INDEX options= RANGE SCAN object= SYS_C00866 position= 1 cost= 1 ・ヒントオプションで /*+ PARALLEL(受注m, 8) */ を指定すると、 マルチ CPU で多重度を利用して実行計画を立てる。 object_node、other に情報が入る。 サーバのプロセス設定など必要である。 truncate table plan_table; explain plan for select /*+ PARALLEL(受注m, 8) */ * from sak.受注m where 受注番号 = '000001-001' ; select operation || ' options= ' || options || ' object= ' || object_name || ' position= ' || position || ' cost= ' || ' object_node= ' || object_node, other from plan_table; ・ヒントオプションで /*+ RULE */ を指定すると、基本のルールベースでの 実行計画を立てるように指示できる。 truncate table plan_table; explain plan for select /*+ RULE */ * from sak.受注m where 受注番号 = '000001-001' ; select operation || ' options= ' || options || ' object= ' || object_name || ' position= ' || position || ' cost= ' || cost from plan_table; 【SELECT STATEMENT options= object= position= cost= 【TABLE ACCESS options= BY INDEX ROWID object= 受注M position= 1 cost= 【INDEX options= UNIQUE SCAN object= SYS_C00866 position= 1 cost= ・ヒントオプションで /*+ ALL_ROWS */ を指定すると、表結合を一番速く実 行する計画を立てる。 truncate table plan_table; explain plan for select /*+ ALL_ROWS */ 受注番号, 受注m.品番 as 品番, 受注m.受注数 as 受注数, 品番m.受注数 as 受注累積, 受注m.得意先CD as 得意先CD, 得意先名, 受注m.更新担当者 as 更新担当者, 受注m.更新日付 as 更新日付, 受注m.更新時間 as 更新時間 from sak.受注m, sak.品番m, sak.得意先m where 受注m.品番 = 品番m.品番 (+) and 受注m.得意先CD = 得意先m.得意先CD (+) ; select operation || ' options= ' || options || ' object= ' || object_name || ' position= ' || position || ' cost= ' || cost from plan_table; 【SELECT STATEMENT options= object= position= 6 cost= 6 【HASH JOIN options= OUTER object= position= 1 cost= 6 【HASH JOIN options= OUTER object= position= 1 cost= 4 【TABLE ACCESS options= FULL object= 受注M position= 1 cost= 1 【TABLE ACCESS options= FULL object= 品番M position= 2 cost= 1 【TABLE ACCESS options= FULL object= 得意先M position= 2 cost= 1 ・ヒントオプションで /*+ FIRST_ROWS */ を指定すると、1 レコード目を 一番速く返す実行計画を立てる。(複数レコードを問い合わせると遅い) truncate table plan_table; explain plan for select /*+ FIRST_ROWS */ 受注番号, 受注m.品番 as 品番, 受注m.受注数 as 受注数, 品番m.受注数 as 受注累積, 受注m.得意先CD as 得意先CD, 得意先名, 受注m.更新担当者 as 更新担当者, 受注m.更新日付 as 更新日付, 受注m.更新時間 as 更新時間 from sak.受注m, sak.品番m, sak.得意先m where 受注m.品番 = 品番m.品番 (+) and 受注m.得意先CD = 得意先m.得意先CD (+) ; select operation || ' options= ' || options || ' object= ' || object_name || ' position= ' || position || ' cost= ' || cost from plan_table; 【SELECT STATEMENT options= object= position= 51 cost= 51 【NESTED LOOPS options= OUTER object= position= 1 cost= 51 【NESTED LOOPS options= OUTER object= position= 1 cost= 42 【TABLE ACCESS options= FULL object= 受注M position= 1 cost= 1 【TABLE ACCESS options= BY INDEX ROWID object= 品番M position= 2 cost= 1 【INDEX options= UNIQUE SCAN object= SYS_C00699 position= 1 cost= 【TABLE ACCESS options= BY INDEX ROWID object= 得意先M position= 2 cost= 1 【INDEX options= UNIQUE SCAN object= SYS_C00701 position= 1 cost= ■SQL チューニング編資料
■SQL 基礎実地編資料
■SQL 基礎編資料
■Oracle PL/SQL 編資料
■PostgreSQL 編、JAVA Servlet、JSP 編資料
■MySQL 編資料