Statement Level Optimizer Hints
Statement level optimizer hints are comments in a SQL statement that pass instructions to the TimesTen query optimizer. The optimizer considers these hints when choosing the best execution plan for your query. It analyzes the SQL statements and generates a query plan which is then used by the SQL execution engine to execute the query and return the data.
See Use Optimizer Hints to Modify the Execution Plan in Oracle TimesTen In-Memory Database Operations Guide for information about statement level optimizer hints.
SQL Syntax
A SQL statement can have one comment that includes one or more statement level optimizer hints.TT_DynamicLoadMultiplePKs
TT_DynamicLoadRootTbl
TT_DynamicPassThrough
Some hints are not supported in certain SQL statements:
-
TT_CommitDMLOnSuccess
is supported in theDELETE
,INSERT
, andUPDATE
statements. It is also valid in theINSERT...SELECT
statement and must follow theSELECT
keyword. This hint is supported in TimesTen Scaleout only. -
The
TT_GridQueryExec
andTT_PartialResult
hints are supported in theSELECT
,INSERT...SELECT
, andCREATE TABLE... AS SELECT
SQL statements only and these hints must follow theSELECT
keyword. These hints are supported in TimesTen Scaleout only. -
The remaining hints are supported in the
DELETE
,INSERT
,MERGE
,SELECT
,UPDATE
,INSERT...SELECT
, andCREATE
TABLE...AS SELECT
SQL statements and these hints must follow theDELETE
,INSERT
,MERGE
,SELECT
, orUPDATE
keyword.
You embed statement level optimizer hints in comment syntax. TimesTen supports hints in comments that span one line and in comments that span more than one line. If your comment that contains the hint spans one or more lines, use the comment syntax, /*+...*/
. If your comment that contains the hint spans one line, use the comment syntax, --+
.
Syntax:
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|
Parameters
Parameter | Description |
---|---|
|
The |
|
One or more hints that are embedded in comment syntax. The comment syntax can span one or more lines. The plus sign ( Make sure there is no space between the star ( |
|
One or more hints that are embedded in comment syntax. The comment syntax can only span one line. The plus sign ( Make sure there is no space between the dash ( |
|
A statement level optimizer hint. A SQL statement supports one or more statement level optimizer hints as one comment string. For one SQL statement, you can specify one comment that contains one or more hints and that comment must follow a If you specify more than one hint within the comment, make sure there is a space between the hints. Statement level optimizer hints are scoped to a SQL statement and have per query semantics. For hints other than
|
|
Text within a comment string. You can use both statement level optimizer hints and commenting text within one comment. Make sure to include a space between the hint and the commenting text. |
|
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 refers to the supported optimizer hints for TimesTen Cache. These hints are TT_DynamicLoadMultiplePKs , TT_DynamicLoadRootTbl , and TT_DynamicPassthrough . These hints are described later in this table (in alphabetical order).
|
|
Specify
For example, if you are joining the Command> SELECT /*+ TT_JoinOrder (EMPS DEPTS)*/... If your You can execute the built-in procedure, For more information on |
|
Specify a value of 0 to ask the optimizer not to consider the index. Specify a value of 1 to ask the optimizer to consider the index. For example, To direct the optimizer to use the index Command> SELECT /*+ TT_INDEX (E,EMP_NAME_IX,1) */ ... Use a semicolon (;) to include more than one If your You can execute the built-in procedure, For more information on |
|
Statement level optimizer hint flags are in effect for the statement only whereas transaction level optimizer hint flags are in effect for the duration of your transaction. |
|
Flag that maps to the flag |
|
This hint controls the return data type for the This hint is provided for backward compatibility. If you specify the hint with a value of This example specifies a value of Command> describe SELECT /*+TT_CountAsInt(1)*/ COUNT (*) FROM dual; Prepared Statement: Columns: EXP TT_INTEGER NOT NULL This example specifies a value of Command> describe SELECT /*+TT_CountAsInt(0)*/ COUNT (*) FROM dual; Prepared Statement: Columns: EXP TT_BIGINT NOT NULL This example does not set the optimizer hint. The default return data type is describe SELECT COUNT (*) FROM dual; Prepared Statement: Columns: EXP TT_BIGINT NOT NULL |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
TT_DynamicLoadMultiplePKs{ 0|1} |
TimesTen Cache optimizer hint, supported in TimesTen Classic. This hint enables (if set to 1 ) or disables (if set to 0 ), the ability to dynamically load multiple cache instances on a single table cache group. The dynamic load operation must be triggered by a qualified SELECT statement that contains a WHERE clause, in which the WHERE clause references multiple primary key values of the root table of the cache group. The default is 1 . When both the TT_DynamicLoadMultiplePKs and the TT_DynamicLoadRootTbl hints are specified, the TT_DynamicLoadMultiplePKs take precedence.
|
TT_DynamicLoadRootTbl |
TimesTen Cache optimizer hint, supported in TimesTen Classic. This hint enables (if set to 1 ) or disables (if set to 0 ), the ability to dynamically load multiple cache instances on a single table cache group. The dynamic load operation must be triggered by a qualified SELECT statement that contains a WHERE clause, in which the WHERE clause does not reference multiple primary key values of the root table of the cache group. The default is 0 . When both the TT_DynamicLoadMultiplePKs and the TT_DynamicLoadRootTbl hints are specified, the TT_DynamicLoadMultiplePKs take precedence.
|
TT_DynamicPassThrough(N) |
TimesTen Cache optimizer hint, supported in TimesTen Classic. If specified, this hint limits the number of rows that can be dynamically loaded into a TimesTen cache instance. Specifically, if a dynamic load operation triggered by a qualified SELECT statement results in a number of rows that is greater than the specified N row limit, the cache instance is not loaded and instead the query is passed to the Oracle database. The dynamic load must be triggered by a qualified SELECT statement and the cache group must not have a WHERE clause. The hint is ignored for non-SELECT statements. Set this hint to the maximum number of rows you want dynamically loaded. If you set the hint to a value less than or equal to 0 or if you do not specify the hint, the dynamic load has no row limit. In this case, there is not a limit in the number of rows can be loaded into the cache instance. See Automatic Passthrough of Dynamic Load to the Oracle Database in the Oracle TimesTen In-Memory Database Cache
Guide for details.
|
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
|
Flag that maps to the flag |
Note:
For descriptions of flags discussed in the preceding table, see ttOptSetFlag" in the Oracle TimesTen In-Memory Database Reference
Description
-
Embed statement level optimizer hints in comment syntax. Begin the comment with either
/*
or--
. Follow the beginning comment syntax with a plus sign (+
). The plus sign (+
) signals TimesTen to interpret the comment as a list of hints. The plus sign (+) must follow immediately after the comment delimiter. (For example, after/*
or after--
). No space is permitted between the comment delimiter and the plus sign (+).In the following example, there is a space between the star (*) and the plus sign (+), so the hint is ignored:
Command> SELECT /* + TT_TblScan (1) This hint is ignored because there is a space between the star (*) and the plus (+) sign. */ ...
-
A
hint
is one of the statement level optimizer hints supported by TimesTen. There can be a space between the plus sign (+) and the hint. If the comment contains multiple hints, separate the hints by at least one space. For example, to specify two hints on one line:Command> SELECT --+ TT_MergeJoin (0) TT_NestedLoop (1) ...
-
You can intersperse commenting text with hints in a comment. For example,
Command> SELECT /*+ TT_HashScan (1) This demonstrates a hint followed by a comment string. */ ...
-
TimesTen ignores hints and does not return an error if:
-
Your hint does not follow the
DELETE
,INSERT
,MERGE
,SELECT
orUPDATE
keyword (or forTT_GridQueryExec
orTT_PartialResult
, theSELECT
keyword).TT_CommitDMLOnSuccess
must follow theDELETE
,INSERT
,UPDATE
keyword and forINSERT...SELECT
, it must follow theSELECT
keyword. -
Your hint contains misspellings or syntax errors. If you have hints that are within the same comment and some hints are correct syntactically and some hints are incorrect syntactically, TimesTen ignores the incorrect hints and accepts the correct hints.
-
You use either the
TT_JoinOrder
orTT_Index
hint and you do not supply a closing parenthesis, the remainder of the hint string is ignored.
-
-
For hints that conflict with each other, TimesTen uses the rightmost hint in the comment. For example, if the comment string is
/*+TT_TblScan (0)...TT_TblScan (1) */
, the rightmost hint,TT_TblScan(1)
, is used. -
Statement level optimizer hints override conflicting transaction level optimizer hints. If you specify a transaction level optimizer hint that conflicts with a statement level optimizer hint, the statement level optimizer hint overrides the conflicting transaction level optimizer hint. For example, if you call
ttOptSetFlag
, and enable theRange
flag and then you issue a SQL query and disable the statement level optimizer flag,TT_Range
, TimesTen disables the range flag for the query. After the query is executed, the original range flag setting that was in place in the transaction before the query was executed remains in effect for the duration of the transaction. For more information, see Using Statement Level Optimizer Hints for a SELECT Query. TheTT_GridQueryExec
,TT_PartialResult
,TT_CommitDMLOnSuccess
, andTT_CountAsInt
hints are not supported at the transaction level. -
Do not use statement level optimizer hints in a subquery.
-
The TimesTen query optimizer does not recognize statement level optimizer hints for passthrough statements. TimesTen passes the SQL text for passthrough statements to the Oracle database and the SQL text is processed according to the SQL rules of the Oracle database. Passthrough statements are not supported in TimesTen Scaleout.
SQL Statements that Support Statement Level Optimizer Hints
You can specify statement level optimizer hints in SQL statements. Not all hints are supported in all statements. You must specify the hint within comment syntax and the comment syntax must immediately follow the SQL
VERB
. (For example, SELECT
/*+
hint
*
/...
) Table 6-3 shows the correct placement of the statement level hint. It also indicates if a hint is not supported in the statement.
Table 6-3 Placement of Statement Level Hints in SQL Statements
SQL Statement | Placement of Hint |
---|---|
|
Do not use transaction level hints with the
|
|
The |
|
The |
|
|
|
The |
|
Do not specify a hint in a subquery. The |
|
The |
|
The |
Understanding Hints
Use optimizer hints to influence the TimesTen query optimizer in determining the choice of the execution plan for your query.
TT_GridQueryExec
, TT_PartialResult
and TT_CommitDMLOnSuccess
are supported at the connection and statement levels only. This section is not valid for these hints.
To view transaction level optimizer hints, execute the built-in procedure, ttOptSetFlag
. For more information on the built-in procedure, ttOptGetFlag
, see ttOptGetFlag in Oracle TimesTen In-Memory Database
Reference.
Examples
For TT_CommitDMLOnSuccess
examples, see TT_CommitDMLOnSuccess Optimizer Hint for information.
For TT_GridQueryExec
and TT_PartialResult
examples:
-
See TT_GridQueryExec in the Oracle TimesTen In-Memory Database Scaleout User's Guide.
-
See TT_PartialResult in the Oracle TimesTen In-Memory Database Scaleout User's Guide.
The following examples illustrate usages of statement level and transaction level optimizer hints. The TimesTen optimizer is a cost based query optimizer and generates what it thinks is the most optimal execution plan for your statement. This plan differs from release to release. The plan is based on the indexes that exist on the referenced tables as well as the column and table statistics that are available. When you recompute statistics or change indexes, the TimesTen optimizer may change the execution plan based on the recomputed statistics and index changes. Because the execution plan may vary, these examples are included for demonstration purposes only. Examples include:
Using Statement Level Optimizer Hints for a SELECT Query
View the execution plan for a query. Then use statement level optimizer hints to influence the optimizer to choose a different execution plan. Consider the query:
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;
Use the ttIsql
EXPLAIN
command to view the plan generated by the optimizer. Note:
-
The optimizer performs two range scans using table level locking for both scans.
-
The optimizer uses the
MergeJoin
operation to join the two tables.
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>
Now use statement level optimizer hints to direct the optimizer to perform the scans using row level locking and to use a NestedLoop
operation to join the tables. Set autocommit to on to illustrate that the autocommit setting has no effect because statement level optimizer hints are scoped to the SQL statement.
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>
Prepare the query again without statement level optimizer hints. The optimizer reverts back to the original execution plan because statement level optimizer hints are scoped to the SQL statement.
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>
Using On and Off Hinting
This example illustrates the importance of directing the optimizer to specifically enable or disable hints that perform a similar function. For example, the hash and range hints direct the optimizer to use either a hash or range access path for the table. In order to ensure the optimizer chooses the specific access path, enable one hint and disable all other related hints.
Create a table and create a hash index on the first column of the table and a range index on the second column.
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);
Set autocommit to off and execute the built-in procedure, ttOptGetFlag
, to review the current transaction level optimizer hint settings for the transaction. A setting of 1 means the flag is enabled.
Command> autocommit off; Command> CALL ttOptGetFlag ('Hash'); < Hash, 1 > 1 row found. Command> CALL ttOptGetFlag ('Scan'); < Scan, 1 > 1 row found.
Use the ttIsql
EXPLAIN
command to review the plan for a SELECT
query using a WHERE
clause and dynamic parameters. The optimizer uses a hash scan.
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
Use the statement level optimizer hint TT_Range
to direct the optimizer to use a range scan. Note that the optimizer ignores the TT_Range
hint and uses a hash scan because you did not direct the optimizer to disable the hash scan. Alter the statement and direct the optimizer to use a range scan and not use a hash scan. To accomplish this, enable the statement level optimizer hint TT_Range
and disable the statement level optimizer hint TT_HashScan
. The optimizer no longer ignores the TT_Range
hint.
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
Prepare the query again without using statement level optimizer hints and without issuing a commit or rollback. The optimizer uses the transaction level optimizer hints settings that were in effect before executing the query. The optimizer uses transaction level optimizer hints because statement level optimizer hints are scoped to the SQL statement.
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
Using TT_JoinOrder to Specify a Join Order
Use the statement level optimizer hint TT_JoinOrder
to direct the optimizer to use a specific join order. First use a transaction level optimizer hint to direct the optimizer to use a specific join order for the transaction. Then use a statement level optimizer hint to direct the optimizer to change the join order for the statement only.
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>
Use the statement level optimizer hint, TT_JoinOrder
, to direct the optimizer to override the transaction level join order optimizer hint for the SQL statement only.
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>
Prepare the query again to verify that the join order that was in effect for the transaction remains in effect.
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>
Using the TT_INDEX Statement Level Optimizer Hint
Perform a query on the employees
table that uses the index, emp_name_ix
. Then use the statement level optimizer hint TT_INDEX
to direct the optimizer not to use this index. First run the ttIsql
command, indexes
, to view the indexes for the employees
table.
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.
Use the ttIsql
command, EXPLAIN
, to view the execution plan for a SELECT
query on the employees
table that uses a WHERE
clause on the last_name
column.
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>
Use the statement level optimizer hint, TT_INDEX
, to direct the optimizer not to use the 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'