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
コマンドおよび問合せオプティマイザ・ヒント・コマンドを使用する場合は、自動コミット機能が無効である必要があります。自動コミットを無効にするには、ttIsql
のautocommit
コマンドを使用します。
次の例では、これらのコマンドを使用して問合せオプティマイザの実行計画を変更する方法を示します。
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
およびtryserial
のttIsql
組込みヒント・コマンドを使用して問合せオプティマイザの計画が変更されています。2つ目のバージョンの問合せでは、シリアル・スキャンおよびネステッド・ループ結合ではなく、一時索引スキャン、シリアル・スキャンおよびネステッド・ループが使用されています。
このように、showplan
コマンドをttIsql
の組込み問合せオプティマイザ・ヒント・コマンドと組み合せて使用すると、アプリケーション要件を満たすために使用する実行計画を迅速に決定できます。
SQLコマンド・キャッシュからのコマンドおよび実行計画の表示
コマンドとその実行計画を表示できます。
次の項では、コマンドおよびその実行計画の表示方法について説明します。
SQLコマンド・キャッシュ内のコマンドの表示
ttIsql
のcmdcache
コマンドで、ttSqlCmdCacheInfo
組込みプロシージャが起動され、TimesTen SQLコマンド・キャッシュの内容が表示されます。
「SQLコマンド・キャッシュに格納されたコマンドの表示」を参照してください。
パラメータなしでcmdcache
コマンドを実行する場合、SQLコマンド・キャッシュの内容がすべて表示されます。ttSqlCmdCacheInfo
組込みプロシージャと同様、コマンドIDを指定して、表示する特定のコマンドを指定できます。
また、特定の所有者または問合せテキストと一致するコマンドのみが表示されるように、ttIsql
のcmdcache
コマンドで結果をフィルタ処理できます。
cmdcache
コマンドの構文は次のとおりです。
cmdcache [[by {sqlcmdid | querytext | owner}] <query_substring>
owner
パラメータを指定した場合、結果が所有者によりフィルタ処理され、<query_substring>
により識別され、戻された各コマンドに表示されます。querytext
パラメータを指定した場合、<query_substring>
内で指定された部分文字列を含む問合せがすべて表示されるように結果がフィルタ処理されます。cmdcache
の<query_substring>
など、<query_substring>
のみを指定した場合、コマンドでは<query_substring>
で問合せテキストがフィルタ処理されます。
SQLコマンド・キャッシュでの文に関する問合せ計画の表示
ttIsql
のexplain
コマンドでは、個々のコマンドに関する問合せ計画を表示します。
-
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>
また、ttIsql
のexplain
コマンドで、指定した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