文レベルのオプティマイザ・ヒント
文レベルのオプティマイザ・ヒントは、TimesTen問合せオプティマイザに命令を渡すSQL文のコメントです。問合せに対して最適な実行計画を選択するとき、オプティマイザではこれらのヒントが考慮されます。オプティマイザはSQL文を分析し、SQL実行エンジンで問合せを実行してデータを戻すために使用される問合せ計画を生成します。
文レベルのオプティマイザ・ヒントの詳細は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』の「オプティマイザ・ヒントの使用による実行計画の変更」を参照してください。
SQL構文
SQL文には、文レベルのオプティマイザ・ヒントが1つ以上あるコメントを1つ付けることができます。TT_DynamicLoadMultiplePKsTT_DynamicLoadRootTblTT_DynamicPassThrough
いくつかのヒントは、特定のSQL文ではサポートされていません。
-
TT_CommitDMLOnSuccessは、DELETE、INSERTおよびUPDATE文でサポートされます。INSERT...SELECT文でも有効で、SELECTキーワードの後に記述する必要があります。このヒントは、TimesTen Scaleoutのみでサポートされています。 -
TT_GridQueryExecヒントとTT_PartialResultヒントは、SELECT、INSERT...SELECTおよびCREATE TABLE... AS SELECTSQL文のみでサポートされており、これらのヒントはSELECTキーワードの後に記述する必要があります。これらのヒントは、TimesTen Scaleoutのみでサポートされています。 -
それ以外のヒントは
DELETE、INSERT、MERGE、SELECT、UPDATE、INSERT...SELECTおよびCREATETABLE...AS SELECTSQL文でサポートされており、これらのヒントは、DELETE、INSERT、MERGE、SELECTまたはUPDATEキーワードの後に記述する必要があります。
文レベルのオプティマイザ・ヒントはコメント構文に埋め込みます。TimesTenでは、1行のコメントおよび複数行のコメント内のヒントがサポートされます。ヒントのあるコメントが複数行の場合は、コメント構文/*+...*/を使用します。ヒントのあるコメントが1行の場合は、コメント構文--+を使用します。
構文:
SQL VERB {/*+ [CommentText] hint [{hint|CommentText} [...]] */ | --+ [CommentText] hint [{hint|CommentText} [...]] } hint::= ScaleoutHint | CacheHint | JoinOrderHint | IndexHint| FlagHint ScaleoutHint::= TT_CommitDMLOnSuccess({0|1})|TT_GridQueryExec({LOCAL|GLOBAL})| TT_PartialResult(0|1) CacheHint::= TT_DynamicLoadMultiplePKs ({0|1})|TT_DynamicLoadRootTbl ({0|1})| TT_DynamicPassthrough(N) JoinOrderHint::= TT_JoinOrder (CorrelationName CorrelationName [...]) IndexHint::= TT_Index (CorrelationName,IndexName,{0|1} [;...]) FlagHint::= FlagName (0|1) FlagName::= TT_BranchAndBound|TT_CountAsInt|TT_DynamicLoadEnable| TT_DynamicLoadErrorMode| TT_FirstRow|TT_ForceCompile| TT_GenPlan|TT_HashGb|TT_HashScan|TT_IndexedOr|TT_MergeJoin| TT_NestedLoop|TT_NoRemRowIdOpt|TT_Range|TT_Rowid|TT_RowLock| TT_ShowJoinOrder|TT_TblLock|TT_TblScan|TT_TmpHash|TT_TmpRange| TT_TmpTable|TT_UseBoyerMooreStringSearch|
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
|
|
|
1つ以上のヒントがコメント構文に埋め込まれています。コメント構文は1行または複数行になります。プラス記号( アスタリスク( |
|
|
1つ以上のヒントがコメント構文に埋め込まれています。コメント構文は1行のみになります。プラス記号( ダッシュ( |
|
|
文レベルのオプティマイザ・ヒント。SQL文では、1つのコメント文字列として、1行以上の文レベルのオプティマイザ・ヒントがサポートされます。1つのSQL文に対して1つ以上のヒントが含まれるコメントを1つ指定できます。コメントは コメント内に複数のヒントを指定する場合は、ヒント間にスペースを入れないようにします。 文レベルのオプティマイザ・ヒントは、1つのSQL文を範囲とし、問合せごとにセマンティクスを持ちます。
|
|
|
コメント文字列内のテキスト。文レベルのオプティマイザ・ヒントとコメント・テキストの両方を1つのコメント内で使用できます。ヒントとコメント・テキスト間にスペースを入れるようにしてください。 |
|
|
SELECT /*+TT_GridQueryExec(LOCAL)*/
COUNT(*), elementId# FROM t
GROUP BY elementId#;SELECT /*+TT_GridQueryExec(GLOBAL)*/
COUNT(*), elementId# FROM t
GROUP BY elementId#;SELECT /*+TT_PartialResult(0)*/ COUNT
(*), elementId# FROM t GROUP BY
elementId#;SELECT /*+TT_PartialResult(1)*/ COUNT
(*), elementId# FROM t GROUP BY
elementId#; |
CacheHint |
CacheHintは、TimesTen Cacheでサポートされているオプティマイザ・ヒントを表します。これに該当するヒントは、TT_DynamicLoadMultiplePKs、TT_DynamicLoadRootTblおよびTT_DynamicPassthroughです。これらのヒントについては、この表で後述します(アルファベット順)。
|
|
|
たとえば、 Command> SELECT /*+ TT_JoinOrder (EMPS DEPTS)*/...
組込みプロシージャ
|
|
|
オプティマイザで索引を考慮しないようにするには、0を指定します。オプティマイザで索引を考慮するようにするには、1を指定します。 たとえば、 Command> SELECT /*+ TT_INDEX (E,EMP_NAME_IX,1) */ ...
組込みプロシージャ
|
|
|
文レベルのオプティマイザ・ヒント・フラグは文のみで有効で、トランザクション・レベルのオプティマイザ・ヒント・フラグはトランザクション中に有効です。 |
|
|
組込みプロシージャ |
|
|
このヒントは、 このヒントは、下位互換性を確保するためのものです。 この例では、ヒントに Command> describe SELECT /*+TT_CountAsInt(1)*/ COUNT (*) FROM dual;
Prepared Statement:
Columns:
EXP TT_INTEGER NOT NULL
この例では、ヒントに Command> describe SELECT /*+TT_CountAsInt(0)*/ COUNT (*) FROM dual;
Prepared Statement:
Columns:
EXP TT_BIGINT NOT NULL
この例では、オプティマイザ・ヒントを設定していません。デフォルトの戻り型は、 describe SELECT COUNT (*) FROM dual;
Prepared Statement:
Columns:
EXP TT_BIGINT NOT NULL
|
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
TT_DynamicLoadMultiplePKs{ 0|1} |
TimesTen ClassicでサポートされているTimesTen Cacheオプティマイザ・ヒント。このヒントでは、単一表キャッシュ・グループに複数のキャッシュ・インスタンスを動的にロードする機能を有効化(1に設定)または無効化(0に設定)します。動的ロードの操作は、WHERE句が含まれている修飾されたSELECT文でトリガーする必要があります。この文では、WHERE句でキャッシュ・グループのルート表の複数の主キー値を参照しています。デフォルトは1です。TT_DynamicLoadMultiplePKsとTT_DynamicLoadRootTblの両方のヒントが指定されている場合は、TT_DynamicLoadMultiplePKsが優先されます。
|
TT_DynamicLoadRootTbl |
TimesTen ClassicでサポートされているTimesTen Cacheオプティマイザ・ヒント。このヒントでは、単一表キャッシュ・グループに複数のキャッシュ・インスタンスを動的にロードする機能を有効化(1に設定)または無効化(0に設定)します。動的ロードの操作は、WHERE句が含まれている修飾されたSELECT文でトリガーする必要があります。この文では、WHERE句がキャッシュ・グループのルート表の複数の主キー値を参照しません。デフォルトは0です。TT_DynamicLoadMultiplePKsとTT_DynamicLoadRootTblの両方のヒントが指定されている場合は、TT_DynamicLoadMultiplePKsが優先されます。
|
TT_DynamicPassThrough(N) |
TimesTen ClassicでサポートされているTimesTen Cacheオプティマイザ・ヒント。指定すると、このヒントによってTimesTenのキャッシュ・インスタンスに動的にロードできる行数が制限されます。具体的には、修飾されたSELECT文によってトリガーされる動的ロード操作によって、指定されたN行の制限を超える行数が生成される場合、キャッシュ・インスタンスはロードされず、問合せはOracleデータベースに渡されます。動的ロードは、修飾されたSELECT文によってトリガーする必要があります。また、キャッシュ・グループにはWHERE句を指定しないでください。ヒントはSELECT以外の文では無視されます。このヒントは、動的にロードする最大行数に設定します。このヒントの値を0以下に設定した場合や、ヒントを指定しない場合は、動的ロードの行制限がなくなります。この場合、キャッシュ・インスタンスにロードできる行数に制限はありません。詳細は、『Oracle TimesTen In-Memory Databaseキャッシュ・ガイド』の「Oracle Databaseへの動的ロードの自動パススルー」を参照してください。
|
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
|
|
組込みプロシージャ |
ノート:
前の表に示したフラグの詳細は、『Oracle TimesTen In-Memory Databaseリファレンス』の「ttOptSetFlag」を参照してください
説明
-
コメント構文に文レベルのオプティマイザ・ヒントを埋め込みます。
/*または—でコメントを開始します。コメント構文を開始した後、プラス記号(+)を追加します。プラス記号(+)により、TimesTenではコメントがヒントのリストとして解釈されます。プラス記号(+)はコメント・デリミタの直後に記述する必要があります。(たとえば、/*または--の後)。コメント・デリミタとプラス記号(+)の間にはスペースを入れません。次の例では、アスタリスク(*)とプラス記号(+)の間にスペースがあるため、ヒントは無視されます。
Command> SELECT /* + TT_TblScan (1) This hint is ignored because there is a space between the star (*) and the plus (+) sign. */ ...
-
hintは、TimesTenでサポートされる文レベルのオプティマイザ・ヒントの1つです。プラス記号(+)とヒントの間にスペースを入れることができます。コメントに複数のヒントがある場合は、1つ以上のスペースでヒントを区切ります。たとえば、1行で2つのヒントを指定するには、次のように実行します。Command> SELECT --+ TT_MergeJoin (0) TT_NestedLoop (1) ...
-
コメント内のヒントにコメント・テキストを組み入れることができます。次に例を示します
Command> SELECT /*+ TT_HashScan (1) This demonstrates a hint followed by a comment string. */ ...
-
TimesTenでは、次の場合にコメントが無視され、エラーは戻されません。
-
ヒントが
DELETE、INSERT、MERGE、SELECTまたはUPDATEキーワード(またはTT_GridQueryExecまたはTT_PartialResultの場合はSELECTキーワード)の後に記述されていない場合。TT_CommitDMLOnSuccessは、DELETE、INSERT、UPDATEキーワードの後に記述する必要があります。INSERT...SELECTでは、SELECTキーワードの後に記述する必要があります。 -
ヒントにスペルミスや構文エラーがある場合。同じコメント内に複数のヒントがあり、構文的に正しいヒントと構文的に正しくないヒントがある場合、TimesTenでは、不正なヒントは無視され、正しいヒントが採用されます。
-
TT_JoinOrderヒントかTT_Indexヒントのいずれかを使用し、閉じカッコがないと、残りのヒント文字列は無視されます。
-
-
互いに競合するヒントがある場合、コメントの右端のヒントが使用されます。たとえば、コメント文字列が
/*+TT_TblScan (0)...TT_TblScan (1) */の場合は、右端のTT_TblScan(1)が使用されます。 -
文レベルのオプティマイザ・ヒントは、競合するトランザクション・レベルのオプティマイザ・ヒントをオーバーライドします。文レベルのオプティマイザ・ヒントと競合するトランザクション・レベルのオプティマイザ・ヒントを指定すると、文レベルのオプティマイザ・ヒントは、競合するトランザクション・レベルのオプティマイザ・ヒントをオーバーライドします。たとえば、
ttOptSetFlagを呼び出し、範囲フラグを有効にし、SQL問合せを発行して文レベルのオプティマイザ・フラグTT_Rangeを無効にすると、この問合せの範囲フラグが無効になります。問合せを実行した後、問合せ実行前にトランザクションに配置された元の範囲フラグ設定は、トランザクション実行中は有効のままです。詳細は、「SELECT問合せでの文レベルのオプティマイザ・ヒントの使用」を参照してください。TT_GridQueryExec、TT_PartialResult、TT_CommitDMLOnSuccessおよびTT_CountAsIntのヒントは、トランザクション・レベルではサポートされていません。 -
副問合せでは文レベルのオプティマイザ・ヒントを使用しないでください。
-
TimesTen問合せオプティマイザは、パススルー文の文レベルのオプティマイザ・ヒントを認識しません。TimesTenでは、パススルー文のSQLテキストはOracle Databaseに渡され、Oracle DatabaseのSQL規則に従って処理されます。パススルー文は、TimesTen Scaleoutではサポートされていません。
文レベルのオプティマイザ・ヒントをサポートするSQL文
SQL文で文レベル・オプティマイザ・ヒントを指定できます。すべてのヒントがすべての文でサポートされているわけではありません。ヒントはコメント構文内に指定し、コメント構文はSQL VERBの直後に記述します。(たとえば、SELECT /*+ hint */...)。表6-3に、文レベルのヒントの正しい配置を示します。ヒントがその文でサポートされていないかどうかも示します。
表6-3 SQL文への文レベルのヒントの配置
| SQL文 | ヒントの配置 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
副問合せではヒントを指定しないでください。
|
|
|
|
|
|
|
ヒントの理解
ヒントを使用することで、問合せの実行計画の選択決定においてTimesTen問合せオプティマイザに作用することができます。
TT_GridQueryExec、TT_PartialResultおよびTT_CommitDMLOnSuccessは、接続レベルと文レベルでのみサポートされています。この項は、これらのヒントに対して有効ではありません。
トランザクション・レベルのオプティマイザ・ヒントを表示するには、組込みプロシージャttOptSetFlagを実行します。組込みプロシージャttOptGetFlagの詳細は、『Oracle TimesTen In-Memory Databaseリファレンス』の「ttOptGetFlag」を参照してください。
例
TT_CommitDMLOnSuccessの例は、「TT_CommitDMLOnSuccessオプティマイザ・ヒント」を参照してください。
TT_GridQueryExecおよびTT_PartialResultの例:
-
『Oracle TimesTen In-Memory Database Scaleoutユーザーズ・ガイド』の「TT_GridQueryExec」を参照してください。
-
『Oracle TimesTen In-Memory Database Scaleoutユーザーズ・ガイド』の「TT_PartialResult」を参照してください。
次の例は、文レベルのオプティマイザ・ヒントとトランザクション・レベルのオプティマイザ・ヒントの使用方法を説明しています。TimesTenオプティマイザは、コストベースのオプティマイザであり、文の最適な実行計画を判断して生成します。この計画は、リリース間で異なります。実行計画は、参照する表にある索引の他に、列および表の利用可能な統計に基づきます。統計の再計算や索引の変更時は、TimesTenオプティマイザは、再計算された統計および索引変更に基づいて実行計画を変更する場合があります。実行計画は多様なため、これらの例はあくまで実例です。次の例があります:
SELECT問合せでの文レベルのオプティマイザ・ヒントの使用
問合せの実行計画を表示します。次に、文レベルのオプティマイザ・ヒントを使用して、オプティマイザに別の実行計画を選択するように指示します。次の問合せについて考えてみます:
Command> SELECT r.region_name, c.country_name
FROM regions r, countries c
WHERE r.region_id = c.region_id
ORDER BY c.region_id;
ttIsql EXPLAINコマンドを使用してオプティマイザが生成した計画を表示します。ノート:
-
オプティマイザは、それぞれのスキャンに表レベル・ロッキングを使用して2つの範囲スキャンを実行します。
-
オプティマイザは、
MergeJoin処理を使用して2つの表を結合します。
Command> EXPLAIN SELECT r.region_name, c.country_name
FROM regions r, countries c
WHERE r.region_id = c.region_id
ORDER BY c.region_id;
Query Optimizer Plan:
STEP: 1
LEVEL: 2
OPERATION: TblLkRangeScan
TBLNAME: COUNTRIES
IXNAME: COUNTR_REG_FK
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
STEP: 2
LEVEL: 2
OPERATION: TblLkRangeScan
TBLNAME: REGIONS
IXNAME: REGIONS
INDEXED CONDITION: R.REGION_ID >= C.REGION_ID
NOT INDEXED: <NULL>
STEP: 3
LEVEL: 1
OPERATION: MergeJoin
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: C.REGION_ID = R.REGION_ID
NOT INDEXED: <NULL>
ここで文レベルのオプティマイザ・ヒントを使用して、低レベル・ロッキングを使用したスキャンの実行、およびNestedLoop処理を使用した表の結合をオプティマイザに指示します。自動コミットをオンに設定すると、文レベルのオプティマイザ・ヒントがSQL文を範囲としているために自動コミット設定が無効になることが分かります。
Command> autocommit on;
Command> EXPLAIN SELECT /*+ TT_RowLock (1), TT_TblLock (0), TT_MergeJoin (0),
TT_NestedLoop (1) */
r.region_name, c.country_name
FROM regions r, countries c
WHERE r.region_id = c.region_id
ORDER BY c.region_id;
Query Optimizer Plan:
STEP: 1
LEVEL: 3
OPERATION: RowLkRangeScan
TBLNAME: REGIONS
IXNAME: REGIONS
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
STEP: 2
LEVEL: 3
OPERATION: RowLkRangeScan
TBLNAME: COUNTRIES
IXNAME: COUNTR_REG_FK
INDEXED CONDITION: C.REGION_ID = R.REGION_ID
NOT INDEXED: <NULL>
STEP: 3
LEVEL: 2
OPERATION: NestedLoop
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
STEP: 4
LEVEL: 1
OPERATION: OrderBy
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
文レベルのオプティマイザ・ヒントなしで問合せを再度準備します。文レベルのオプティマイザ・ヒントがSQL文を範囲とするため、元の実行計画に戻ります。
Command> EXPLAIN SELECT r.region_name, c.country_name
FROM regions r, countries c
WHERE r.region_id = c.region_id
ORDER BY c.region_id;
Query Optimizer Plan:
STEP: 1
LEVEL: 2
OPERATION: TblLkRangeScan
TBLNAME: COUNTRIES
IXNAME: COUNTR_REG_FK
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
STEP: 2
LEVEL: 2
OPERATION: TblLkRangeScan
TBLNAME: REGIONS
IXNAME: REGIONS
INDEXED CONDITION: R.REGION_ID >= C.REGION_ID
NOT INDEXED: <NULL>
STEP: 3
LEVEL: 1
OPERATION: MergeJoin
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: C.REGION_ID = R.REGION_ID
NOT INDEXED: <NULL>ヒントの有効化および無効化
この例は、類似の関数を実行するヒントを有効または無効にするかを明確にオプティマイザに指示することの重要性を示しています。たとえば、ハッシュ・ヒントおよび範囲ヒントにより、表のハッシュ・アクセス・パスまたは範囲アクセス・パスのいずれかを使用するようにオプティマイザに指示する場合です。特定のアクセス・パスをオプティマイザが確実に選択できるよう、1つのヒントを有効にしてその他すべての関連ヒントを無効にします。
表を作成し、表の1列目にハッシュ索引、2列目に範囲索引を作成します。
Command> CREATE TABLE test (col1 NUMBER, col2 NUMBER); Command> CREATE HASH INDEX h_index ON test (col1); Command> CREATE INDEX hr_index ON test (col2);
自動コミットをオフにし、組み込みプロシージャttOptGetFlagを実行して、トランザクションの現在のトランザクション・レベルのオプティマイザ・ヒントを表示します。1に設定すると、フラグは無効です。
Command> autocommit off;
Command> CALL ttOptGetFlag ('Hash');
< Hash, 1 >
1 row found.
Command> CALL ttOptGetFlag ('Scan');
< Scan, 1 >
1 row found.
ttIsq EXPLAINコマンドを使用して、WHERE句と動的パラメータを使用したSELECT問合せの計画を確認します。オプティマイザはハッシュ・スキャンを使用します。
Command> EXPLAIN SELECT * FROM test WHERE col1 = ? and col2 = ?; Query Optimizer Plan: STEP: 1 LEVEL: 1 OPERATION: RowLkHashScan TBLNAME: TEST IXNAME: H_INDEX INDEXED CONDITION: TEST.COL1 = _QMARK_1 NOT INDEXED: TEST.COL2 = _QMARK_2
文レベルのオプティマイザ・ヒントTT_Rangeを使用して、オプティマイザに範囲スキャンの使用を指示します。オプティマイザにハッシュ・スキャンの無効化を指示していないため、オプティマイザはTT_Rangeヒントを無視し、ハッシュ・スキャンを使用します。文を変更し、オプティマイザにハッシュ・スキャンを使用せずに範囲スキャンを使用するように指示します。そのためには、文レベルのオプティマイザ・ヒントTT_Rangeを有効にし、文レベルのオプティマイザ・ヒントTT_HashScanを無効にします。オプティマイザはTT_Rangeヒントを無視しなくなります。
Command> EXPLAIN SELECT --+ TT_Range (1) Single line comment to set TT_Range
* FROM TEST WHERE col1 = ? and col2 = ?;
Query Optimizer Plan:
STEP: 1
LEVEL: 1
OPERATION: RowLkHashScan
TBLNAME: TEST
IXNAME: H_INDEX
INDEXED CONDITION: TEST.COL1 = _QMARK_1
NOT INDEXED: TEST.COL2 = _QMARK_2
Command> EXPLAIN SELECT /*+ TT_Range (1) TT_HashScan (0)
Multiple line comment to enable TT_Range and disable TT_HashScan */
* FROM TEST WHERE col1 = ? and col2 = ?;
Query Optimizer Plan:
STEP: 1
LEVEL: 1
OPERATION: RowLkRangeScan
TBLNAME: TEST
IXNAME: HR_INDEX
INDEXED CONDITION: TEST.COL2 = _QMARK_2
NOT INDEXED: TEST.COL1 = _QMARK_1
文レベルのオプティマイザ・ヒントを使用せず、コミットやロールバックを発行せずに、問合せを再度準備します。オプティマイザは、問合せの実行前に有効なトランザクション・レベルのオプティマイザ・ヒントを使用します。文レベルのオプティマイザ・ヒントがSQL文を範囲とするため、オプティマイザはトランザクション・レベルのオプティマイザ・ヒントを使用します。
Command> EXPLAIN SELECT * FROM TEST WHERE col1 = ? and col2 = ?; Query Optimizer Plan: STEP: 1 LEVEL: 1 OPERATION: RowLkHashScan TBLNAME: TEST IXNAME: H_INDEX INDEXED CONDITION: TEST.COL1 = _QMARK_1 NOT INDEXED: TEST.COL2 = _QMARK_2
TT_JoinOrderを使用した結合順序の指定
文レベルのオプティマイザ・ヒントTT_JoinOrderを使用して、オプティマイザに特定の結合順序の使用を指示します。まずトランザクション・レベルのオプティマイザ・ヒントを使用して、トランザクションでの特定の結合順序の使用をオプティマイザに指示します。次に文レベルのオプティマイザ・ヒントを使用して、文のみで結合順序の変更をオプティマイザに指示します。
Command> CALL ttOptSetOrder ('e d j');
Command> EXPLAIN SELECT *
FROM employees e, departments d, job_history j
WHERE e.department_id = d.department_id
AND e.hire_date = j.start_date;
Query Optimizer Plan:
STEP: 1
LEVEL: 3
OPERATION: TblLkRangeScan
TBLNAME: EMPLOYEES
IXNAME: EMP_DEPT_FK
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
STEP: 2
LEVEL: 3
OPERATION: TblLkRangeScan
TBLNAME: DEPARTMENTS
IXNAME: DEPARTMENTS
INDEXED CONDITION: D.DEPARTMENT_ID >= E.DEPARTMENT_ID
NOT INDEXED: <NULL>
STEP: 3
LEVEL: 2
OPERATION: MergeJoin
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: E.DEPARTMENT_ID = D.DEPARTMENT_ID
NOT INDEXED: <NULL>
STEP: 4
LEVEL: 2
OPERATION: TblLkRangeScan
TBLNAME: JOB_HISTORY
IXNAME: JOB_HISTORY
INDEXED CONDITION: <NULL>
NOT INDEXED: E.HIRE_DATE = J.START_DATE
STEP: 5
LEVEL: 1
OPERATION: NestedLoop
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
トランザクション・レベルの結合順序オプティマイザ・ヒントを、そのSQL文に対してのみオーバーライドするようオプティマイザに指示するには、文レベルのオプティマイザ・ヒントTT_JoinOrderを使用します。
Command> EXPLAIN SELECT --+ TT_JoinOrder (e j d)
*
FROM employees e, departments d, job_history j
WHERE e.department_id = d.department_id
AND e.hire_date = j.start_date;
Query Optimizer Plan:
STEP: 1
LEVEL: 3
OPERATION: TblLkRangeScan
TBLNAME: EMPLOYEES
IXNAME: EMP_DEPT_FK
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
STEP: 2
LEVEL: 3
OPERATION: TblLkRangeScan
TBLNAME: JOB_HISTORY
IXNAME: JOB_HISTORY
INDEXED CONDITION: <NULL>
NOT INDEXED: E.HIRE_DATE = J.START_DATE
STEP: 3
LEVEL: 2
OPERATION: NestedLoop
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
STEP: 4
LEVEL: 2
OPERATION: TblLkRangeScan
TBLNAME: DEPARTMENTS
IXNAME: DEPARTMENTS
INDEXED CONDITION: D.DEPARTMENT_ID >= E.DEPARTMENT_ID
NOT INDEXED: <NULL>
STEP: 5
LEVEL: 1
OPERATION: MergeJoin
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: E.DEPARTMENT_ID = D.DEPARTMENT_ID
NOT INDEXED: <NULL>
問合せを再度準備し、トランザクションで有効だった結合順序が有効のままであるかを確認します。
Command> EXPLAIN SELECT *
FROM employees e, departments d, job_history j
WHERE e.department_id = d.department_id
AND e.hire_date = j.start_date;
Query Optimizer Plan:
STEP: 1
LEVEL: 3
OPERATION: TblLkRangeScan
TBLNAME: EMPLOYEES
IXNAME: EMP_DEPT_FK
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>
STEP: 2
LEVEL: 3
OPERATION: TblLkRangeScan
TBLNAME: DEPARTMENTS
IXNAME: DEPARTMENTS
INDEXED CONDITION: D.DEPARTMENT_ID >= E.DEPARTMENT_ID
NOT INDEXED: <NULL>
STEP: 3
LEVEL: 2
OPERATION: MergeJoin
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: E.DEPARTMENT_ID = D.DEPARTMENT_ID
NOT INDEXED: <NULL>
STEP: 4
LEVEL: 2
OPERATION: TblLkRangeScan
TBLNAME: JOB_HISTORY
IXNAME: JOB_HISTORY
INDEXED CONDITION: <NULL>
NOT INDEXED: E.HIRE_DATE = J.START_DATE
STEP: 5
LEVEL: 1
OPERATION: NestedLoop
TBLNAME: <NULL>
IXNAME: <NULL>
INDEXED CONDITION: <NULL>
NOT INDEXED: <NULL>文レベルのオプティマイザ・ヒントTT_INDEXの使用
emp_name_ix索引を使用するemployees表で問合せを実行します。次に、文レベルのオプティマイザ・ヒントTT_INDEXを使用して、この索引を使用しないことをオプティマイザに指示します。まずttIsqlコマンドindexesを実行し、employees表の索引を表示します。
Command> indexes employees;
Indexes on table TESTUSER.EMPLOYEES:
EMPLOYEES: unique range index on columns:
EMPLOYEE_ID
(referenced by foreign key index JHIST_EMP_FK on table TESTUSER.JOB_HISTORY)
TTUNIQUE_0: unique range index on columns:
EMAIL
EMP_DEPT_FK: non-unique range index on columns:
DEPARTMENT_ID
(foreign key index references table TESTUSER.DEPARTMENTS(DEPARTMENT_ID))
EMP_JOB_FK: non-unique range index on columns:
JOB_ID
(foreign key index references table TESTUSER.JOBS(JOB_ID))
EMP_NAME_IX: non-unique range index on columns:
LAST_NAME
FIRST_NAME
5 indexes found.
5 indexes found on 1 table.
ttIsqlコマンドEXPLAINを使用して、last_name列でWHERE句を使用するemployees表でのSELECT問合せの実行計画を表示します。
Command> EXPLAIN SELECT e.first_name
FROM employees e
WHERE e.last_name BETWEEN 'A' AND 'B';
Query Optimizer Plan:
STEP: 1
LEVEL: 1
OPERATION: RowLkRangeScan
TBLNAME: EMPLOYEES
IXNAME: EMP_NAME_IX
INDEXED CONDITION: E.LAST_NAME >= 'A' AND E.LAST_NAME <= 'B'
NOT INDEXED: <NULL>
文レベルのオプティマイザ・ヒントTT_INDEXを使用して、索引emp_name_ixを使用しないことをオプティマイザに指示します。
Command> EXPLAIN SELECT --+ TT_INDEX (E,EMP_NAME_IX,0)
e.first_name
FROM employees e
WHERE e.last_name BETWEEN 'A' AND 'B';
Query Optimizer Plan:
STEP: 1
LEVEL: 1
OPERATION: TblLkRangeScan
TBLNAME: EMPLOYEES
IXNAME: EMPLOYEES
INDEXED CONDITION: <NULL>
NOT INDEXED: E.LAST_NAME <= 'B' AND E.LAST_NAME >= 'A'