ttIsqlの使用による問合せオプティマイザ計画の表示および変更

問合せオプティマイザ計画、SQLコマンド・キャッシュ内のコマンド、またはSQLコマンド・キャッシュ内のコマンドに関する問合せ計画を表示できます。

showplanコマンドの使用

組込みshowplanコマンドを使用すると、TimesTenで問合せの処理に使用される問合せオプティマイザ計画が表示されます。

また、ttIsqlには、この問合せオプティマイザ計画を変更するための組込み問合せオプティマイザ・ヒント・コマンドが用意されています。showplanコマンドと、次に示すttIsqlコマンドを組み合せて使用すると、最適な実行計画を設計できます。TimesTen問合せオプティマイザを参照してください。

  • optprofile - 現行のオプティマイザ・ヒントの設定および結合順序を表示します。

  • setjoinorder - 結合順序を設定します。

  • setuseindex - 索引ヒントを設定します。

  • tryhash - ハッシュ索引の使用を有効または無効にします。

  • trymergejoin: マージ結合を有効または無効にします。

  • trynestedloopjoin - ネステッド・ループ結合を有効または無効にします。

  • tryserial - シリアル・スキャンを有効または無効にします。

  • trytmphash - 一時ハッシュ索引の使用を有効または無効にします。

  • trytmptable - 中間結果表の使用を有効または無効にします。

  • trytmprange: 一時範囲索引の使用を有効または無効にします。

  • tryrange: 範囲索引の使用を有効または無効にします。

  • tryrowid - ROWIDスキャンの使用を有効または無効にします。

  • trytbllocks: 表ロックの使用を有効または無効にします。

  • unsetjoinorder - 結合順序を消去します。

  • unsetuseindex - 索引ヒントを消去します。

showplanコマンドおよび問合せオプティマイザ・ヒント・コマンドを使用する場合は、自動コミット機能が無効である必要があります。自動コミットを無効にするには、ttIsqlautocommitコマンドを使用します。

次の例では、これらのコマンドを使用して問合せオプティマイザの実行計画を変更する方法を示します。

Command> CREATE TABLE T1 (A NUMBER);
Command> CREATE TABLE T2 (B NUMBER);
Command> CREATE TABLE T3 (C NUMBER);
Command> INSERT INTO T1 VALUES (3);
1 row inserted.
Command> INSERT INTO T2 VALUES (3);
1 row inserted.
Command> INSERT INTO T3 VALUES (3);
1 row inserted.
Command> INSERT INTO T1 VALUES (4);
1 row inserted.
Command> INSERT INTO T2 VALUES (5);
1 row inserted.
Command> INSERT INTO T3 VALUES (6);
1 row inserted.
Command> autocommit 0;
Command> showplan;
Command> SELECT * FROM T1, T2, T3 WHERE A=B AND B=C AND A=B;

Query Optimizer Plan:
 
  STEP:                1
  LEVEL:               3
  OPERATION:           TblLkSerialScan
  TBLNAME:             T2
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         <NULL>
 
 
  STEP:                2
  LEVEL:               3
  OPERATION:           TblLkSerialScan
  TBLNAME:             T3
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         T2.B = T3.C
 
 
  STEP:                3
  LEVEL:               2
  OPERATION:           NestedLoop
  TBLNAME:             <NULL>
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         <NULL>
 
 
  STEP:                4
  LEVEL:               2
  OPERATION:           TblLkSerialScan
  TBLNAME:             T1
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         T1.A = T2.B AND T1.A = T2.B
 
 
  STEP:                5
  LEVEL:               1
  OPERATION:           NestedLoop
  TBLNAME:             <NULL>
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         <NULL>
 
< 3, 3, 3 >
1 row found.

Command> trytbllocks 0;
Command> tryserial 0;
Command> SELECT * FROM T1, T2, T3 WHERE A=B AND B=C AND A=B;

Query Optimizer Plan:
 
  STEP:                1
  LEVEL:               3
  OPERATION:           TmpRangeScan
  TBLNAME:             T2
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         <NULL>
 
 
  STEP:                2
  LEVEL:               3
  OPERATION:           RowLkSerialScan
  TBLNAME:             T3
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         T2.B = T3.C
 
 
  STEP:                3
  LEVEL:               2
  OPERATION:           NestedLoop
  TBLNAME:             <NULL>
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         <NULL>
 
 
  STEP:                4
  LEVEL:               2
  OPERATION:           RowLkSerialScan
  TBLNAME:             T1
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         T1.A = T2.B AND T1.A = T2.B
 
 
  STEP:                5
  LEVEL:               1
  OPERATION:           NestedLoop
  TBLNAME:             <NULL>
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         <NULL>
 
< 3, 3, 3 >
1 row found.

この例では、3つの表に対して問合せが実行され、問合せオプティマイザの計画が表示されています。1つ目のバージョンの問合せでは、問合せオプティマイザのデフォルトの実行計画が使用されています。ただし、2つ目のバージョンでは、trytbllocksおよびtryserialttIsql組込みヒント・コマンドを使用して問合せオプティマイザの計画が変更されています。2つ目のバージョンの問合せでは、シリアル・スキャンおよびネステッド・ループ結合ではなく、一時索引スキャン、シリアル・スキャンおよびネステッド・ループが使用されています。

このように、showplanコマンドをttIsqlの組込み問合せオプティマイザ・ヒント・コマンドと組み合せて使用すると、アプリケーション要件を満たすために使用する実行計画を迅速に決定できます。

SQLコマンド・キャッシュからのコマンドおよび実行計画の表示

コマンドとその実行計画を表示できます。

次の項では、コマンドおよびその実行計画の表示方法について説明します。

SQLコマンド・キャッシュ内のコマンドの表示

ttIsqlcmdcacheコマンドで、ttSqlCmdCacheInfo組込みプロシージャが起動され、TimesTen SQLコマンド・キャッシュの内容が表示されます。

「SQLコマンド・キャッシュに格納されたコマンドの表示」を参照してください。

パラメータなしでcmdcacheコマンドを実行する場合、SQLコマンド・キャッシュの内容がすべて表示されます。ttSqlCmdCacheInfo組込みプロシージャと同様、コマンドIDを指定して、表示する特定のコマンドを指定できます。

また、特定の所有者または問合せテキストと一致するコマンドのみが表示されるように、ttIsqlcmdcacheコマンドで結果をフィルタ処理できます。

cmdcacheコマンドの構文は次のとおりです。

cmdcache [[by {sqlcmdid | querytext | owner}] <query_substring>

ownerパラメータを指定した場合、結果が所有者によりフィルタ処理され、<query_substring>により識別され、戻された各コマンドに表示されます。querytextパラメータを指定した場合、<query_substring>内で指定された部分文字列を含む問合せがすべて表示されるように結果がフィルタ処理されます。cmdcache<query_substring>など、<query_substring>のみを指定した場合、コマンドでは<query_substring>で問合せテキストがフィルタ処理されます。

SQLコマンド・キャッシュでの文に関する問合せ計画の表示

ttIsqlexplainコマンドでは、個々のコマンドに関する問合せ計画を表示します。

  • SQLコマンド・キャッシュからコマンドIDを指定した場合、explainコマンドによりttSqlCmdQueryPlan組込みプロシージャが起動され、TimesTen SQLコマンド・キャッシュに格納された個々のコマンドに関する問合せ計画が表示されます。実行計画を書式設定された方法で表示する場合は、ttSqlCmdQueryPlan組込みプロシージャをコールするかわりにexplainコマンドを実行します。両方では同じ情報が得られますが、ttSqlCmdQueryPlan組込みプロシージャではデータはRAWデータ形式で得られます。「SQLコマンド・キャッシュに格納されているコマンドに関連付けられた問合せ計画の表示」を参照してください。

  • SQL文または履歴項目番号を指定した場合、そのSQL文に関する実行計画を表示するために必要なSQL文をexplainコマンドでコンパイルします。

explainコマンドの構文は次のとおりです。

explain [plan for] {[<Connid>.]<ttisqlcmdid> | sqlcmdid <sqlcmdid> | <sqlstmt> 
| !<historyitem>}

ttSqlCmdQueryPlan組込みプロシージャと同様、コマンドIDを提示して、表示する特定のコマンドを指定できます。コマンドIDは、「SQLコマンド・キャッシュ内のコマンドの表示」で説明されているとおり、cmdcacheコマンドで取得できます。

次の例に、38001456というコマンドIDに関する実行計画を示します。

Command> EXPLAIN SQLCMDID 38001456;
 
Query Optimizer Plan:
 Query Text: select * from all_objects where object_name = 'DBMS_OUTPUT'
 
  STEP:             1
  LEVEL:            12
  OPERATION:        TblLkRangeScan
  TABLENAME:        OBJ$
  TABLEOWNERNAME:   SYS
  INDEXNAME:        USER$.I_OBJ
  INDEXEDPRED:      
  NONINDEXEDPRED:   (RTRIM( NAME ))  = DBMS_OUTPUT;NOT( 10 = TYPE#) ;
(  FLAGS ^ 128 = 0) ;
 
 
  STEP:             2
  LEVEL:            12
  OPERATION:        RowLkRangeScan
  TABLENAME:        OBJAUTH$
  TABLEOWNERNAME:   SYS
  INDEXNAME:        OBJAUTH$.I_OBJAUTH1
  INDEXEDPRED:      ( (GRANTEE#=1 )  OR (GRANTEE#=10 ) )  AND ( (PRIVILEGE#=8 ) )
  NONINDEXEDPRED:   OBJ# = OBJ#;
 
 
  STEP:             3
  LEVEL:            11
  OPERATION:        NestedLoop(Left OuterJoin)
  TABLENAME:        
  TABLEOWNERNAME:   
  INDEXNAME:        
  INDEXEDPRED:      
  NONINDEXEDPRED: 
...
 STEP:             21
  LEVEL:            1
  OPERATION:        Project
  TABLENAME:        
  TABLEOWNERNAME:   
  INDEXNAME:        
  INDEXEDPRED:      
  NONINDEXEDPRED:   
 
Command> 

また、ttIsqlexplainコマンドで、指定したSQL問合せに関する実行計画を生成できます。たとえば、SELECT * FROM employees;というSQL問合せに関する実行計画は次のようになります。

Command> EXPLAIN SELECT * FROM employees;
 
Query Optimizer Plan:
 
  STEP:                1
  LEVEL:               1
  OPERATION:           TblLkRangeScan
  TBLNAME:             EMPLOYEES
  IXNAME:              EMP_NAME_IX
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         <NULL>

また、コマンド履歴をもとに実行計画を取得することもできます。次の例では、以前に実行したSQL文の実行計画を、履歴コマンドIDを使用して表示する方法を示します。

Command> SELECT * FROM all_objects WHERE object_name = 'DBMS_OUTPUT';
< SYS, DBMS_OUTPUT, <NULL>, 241, <NULL>, PACKAGE, 2009-10-13 10:41:11, 2009-10-13 
10:41:11, 2009-10-13:10:41:11, VALID, N, N, N, 1, <NULL> >
< PUBLIC, DBMS_OUTPUT, <NULL>, 242, <NULL>, SYNONYM, 2009-10-13 10:41:11, 
2009-10-13 10:41:11, 2009-10-13:10:41:11, INVALID, N, N, N, 1, <NULL> >
< SYS, DBMS_OUTPUT, <NULL>, 243, <NULL>, PACKAGE BODY, 2009-10-13 10:41:11, 
2009-10-13 10:41:11, 2009-10-13:10:41:11, VALID, N, N, N, 2, <NULL> >
3 rows found.
Command> HISTORY;
1     connect "DSN=cache";
2     help cmdcache;
3     cmdcache;
4     explain select * from dual;
5     select * from all_objects where object_name = 'DBMS_OUTPUT';
Command> EXPLAIN !5;
 
Query Optimizer Plan:
 
  STEP:                1
  LEVEL:               10
  OPERATION:           TblLkRangeScan
  TBLNAME:             SYS.OBJ$
  IXNAME:              USER$.I_OBJ
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         O.FLAGS & 128 = 0 AND CAST(RTRIM (O.NAME) AS VARCHAR2(30 
BYTE) INLINE) = 'DBMS_OUTPUT' AND O.TYPE# <> 10
 
  STEP:                2
  LEVEL:               10
  OPERATION:           RowLkRangeScan
  TBLNAME:             SYS.OBJAUTH$
  IXNAME:              OBJAUTH$.I_OBJAUTH1
  INDEXED CONDITION:   (OA.GRANTEE# = 1 OR OA.GRANTEE# = 10) AND OA.PRIVILEGE# = 8
  NOT INDEXED:         OA.OBJ# = O.OBJ#
 
  STEP:                3
  LEVEL:               9
  OPERATION:           NestedLoop(Left OuterJoin)
  TBLNAME:             <NULL>
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         <NULL>
 
  STEP:                4
  LEVEL:               9
  OPERATION:           TblLkRangeScan
  TBLNAME:             SYS.OBJAUTH$
  IXNAME:              OBJAUTH$.I_OBJAUTH1
  INDEXED CONDITION:   (OBJAUTH$.GRANTEE# = 1 OR OBJAUTH$.GRANTEE# = 10) AND 
(OBJAUTH$.PRIVILEGE# = 2 OR OBJAUTH$.PRIVILEGE# = 3 OR OBJAUTH$.PRIVILEGE# = 4 OR 
OBJAUTH$.PRIVILEGE# = 5 OR OBJAUTH$.PRIVILEGE# = 8)
  NOT INDEXED:         O.OBJ# = OBJAUTH$.OBJ#
... 
 STEP:                19
  LEVEL:               1
  OPERATION:           NestedLoop(Left OuterJoin)
  TBLNAME:             <NULL>
  IXNAME:              <NULL>
  INDEXED CONDITION:   <NULL>
  NOT INDEXED:         O.OWNER# = 1 OR (O.TYPE# IN (7,8,9) AND (NOT( ISNULLROW 
(SYS.OBJAUTH$.ROWID)) OR NOT( ISNULLROW (SYS.SYSAUTH$.ROWID)))) OR (O.TYPE# IN 
(1,2,3,4,5) AND NOT( ISNULLROW (SYS.SYSAUTH$.ROWID))) OR (O.TYPE# = 6 AND NOT( 
ISNULLROW (SYS.SYSAUTH$.ROWID))) OR (O.TYPE# = 11 AND NOT( ISNULLROW 
(SYS.SYSAUTH$.ROWID))) OR (O.TYPE# NOT IN (7,8,9,11) AND NOT( ISNULLROW 
(SYS.OBJAUTH$.ROWID))) OR (O.TYPE# = 28 AND NOT( ISNULLROW (SYS.SYSAUTH$.ROWID))) 
OR (O.TYPE# = 23 AND NOT( ISNULLROW (SYS.SYSAUTH$.ROWID))) OR O.OWNER# = 10