You are on page 1of 12

/*+ hint */

/*+ hint(argument) */

/*+ hint(argument-1 argument-2) */

All hints except /*+ rule */ cause the CBO to be used. Therefore, it is good practise to analyze the underlying tables if hints are used (or the query
is fully hinted.
There should be no schema names in hints. Hints must use aliases if alias names are used for table names. So the following is wrong:
select /*+ index(scott.emp ix_emp) */ from scott.emp emp_alias

better:
select /*+ index(emp_alias ix_emp) */ ... from scott.emp emp_alias

Why using hints


It is a perfect valid question to ask why hints should be used. Oracle comes with an optimizer that promises to optimize a query's execution plan.
When this optimizer is really doing a good job, no hints should be required at all.
Sometimes, however, the characteristics of the data in the database are changing rapidly, so that the optimizer (or more accuratly, its statistics)
are out of date. In this case, a hint could help.
It must also be noted, that Oracle allows to lock the statistics when they look ideal which should make the hints meaningless again.

Hint categories
Hints can be categorized as follows:

• Hints for Optimization Approaches and Goals,


• Hints for Access Paths, Hints for Query Transformations,
• Hints for Join Orders,
• Hints for Join Operations,
• Hints for Parallel Execution,
• Additional Hints

Documented Hints

Hints for Optimization Approaches and Goals


• ALL_ROWS
One of the hints that 'invokes' the Cost based optimizer
ALL_ROWS is usually used for batch processing or data warehousing systems.
• FIRST_ROWS
One of the hints that 'invokes' the Cost based optimizer
FIRST_ROWS is usually used for OLTP systems.
• CHOOSE
One of the hints that 'invokes' the Cost based optimizer
This hint lets the server choose (between ALL_ROWS and FIRST_ROWS, based on statistics gathered.
• RULE
The RULE hint should be considered deprecated as it is dropped from Oracle9i2.

See also the following initialization parameters: optimizer_mode, optimizer_max_permutations, optimizer_index_cost_adj,


optimizer_index_caching and

Hints for Access Paths

• CLUSTER
Performs a nested loop by the cluster index of one of the tables.
• FULL
Performs full table scan.
• HASH
Hashes one table (full scan) and creates a hash index for that table. Then hashes other table and uses hash index to find
corresponding records. Therefore not suitable for < or > join conditions.
• ROWID
Retrieves the row by rowid
• INDEX
Specifying that index index_name should be used on table tab_name: /*+ index (tab_name index_name) */
Specifying that the index should be used the the CBO thinks is most suitable. (Not always a good choice).
Starting with Oracle 10g, the index hint can be described: /*+ index(my_tab my_tab(col_1, col_2)) */. Using the index on my_tab that
starts with the columns col_1 and col_2.
• INDEX_ASC
• INDEX_COMBINE
• INDEX_DESC
• INDEX_FFS
• INDEX_JOIN
• NO_INDEX
• AND_EQUAL
The AND_EQUAL hint explicitly chooses an execution plan that uses an access path that merges the scans on several single-
column indexes

Hints for Query Transformations

• FACT
The FACT hint is used in the context of the star transformation to indicate to the transformation that the hinted table should be
considered as a fact table.
• MERGE
• NO_EXPAND
• NO_EXPAND_GSET_TO_UNION
• NO_FACT
• NO_MERGE
• NOREWRITE
• REWRITE
• STAR_TRANSFORMATION
• USE_CONCAT

Hints for Join Operations

• DRIVING_SITE
• HASH_AJ
• HASH_SJ
• LEADING
• MERGE_AJ
• MERGE_SJ
• NL_AJ
• NL_SJ
• USE_HASH
• USE_MERGE
• USE_NL

Hints for Parallel Execution

• NOPARALLEL
• PARALLEL
• NOPARALLEL_INDEX
• PARALLEL_INDEX
• PQ_DISTRIBUTE

Additional Hints

• ANTIJOIN
• APPEND
If a table or an index is specified with nologging, this hint applied with an insert statement produces a direct path insert which
reduces generation of redo.
• BITMAP
• BUFFER
• CACHE
• CARDINALITY
• CPU_COSTING
• DYNAMIC_SAMPLING
• INLINE
• MATERIALIZE
• NO_ACCESS
• NO_BUFFER
• NO_MONITORING
• NO_PUSH_PRED
• NO_PUSH_SUBQ
• NO_QKN_BUFF
• NO_SEMIJOIN
• NOAPPEND
• NOCACHE
• OR_EXPAND
• ORDERED
• ORDERED_PREDICATES
• PUSH_PRED
• PUSH_SUBQ
• QB_NAME
• RESULT_CACHE (Oracle 11g)
• SELECTIVITY
• SEMIJOIN
• SEMIJOIN_DRIVER
• STAR
The STAR hint forces a star query plan to be used, if possible. A star plan has the largest table in the query last in the join order and
joins it with a nested loops join on a concatenated index. The STAR hint applies when there are at least three tables, the large
table's concatenated index has at least three columns, and there are no conflicting access or join method hints. The optimizer also
considers different permutations of the small tables.
• SWAP_JOIN_INPUTS
• USE_ANTI
• USE_SEMI

Undocumented hints:

• BYPASS_RECURSIVE_CHECK
Workaraound for bug 1816154
• BYPASS_UJVC
• CACHE_CB
• CACHE_TEMP_TABLE
• CIV_GB
• COLLECTIONS_GET_REFS
• CUBE_GB
• CURSOR_SHARING_EXACT
• DEREF_NO_REWRITE
• DML_UPDATE
• DOMAIN_INDEX_NO_SORT
• DOMAIN_INDEX_SORT
• DYNAMIC_SAMPLING
• DYNAMIC_SAMPLING_EST_CDN
• EXPAND_GSET_TO_UNION
• FORCE_SAMPLE_BLOCK
• GBY_CONC_ROLLUP
• GLOBAL_TABLE_HINTS
• HWM_BROKERED
• IGNORE_ON_CLAUSE
• IGNORE_WHERE_CLAUSE
• INDEX_RRS
• INDEX_SS
• INDEX_SS_ASC
• INDEX_SS_DESC
• LIKE_EXPAND
• LOCAL_INDEXES
• MV_MERGE
• NESTED_TABLE_GET_REFS
• NESTED_TABLE_SET_REFS
• NESTED_TABLE_SET_SETID
• NO_FILTERING
• NO_ORDER_ROLLUPS
• NO_PRUNE_GSETS
• NO_STATS_GSETS
• NO_UNNEST
• NOCPU_COSTING
• OVERFLOW_NOMOVE
• PIV_GB
• PIV_SSF
• PQ_MAP
• PQ_NOMAP
• REMOTE_MAPPED
• RESTORE_AS_INTERVALS
• SAVE_AS_INTERVALS
• SCN_ASCENDING
• SKIP_EXT_OPTIMIZER
• SQLLDR
• SYS_DL_CURSOR
• SYS_PARALLEL_TXN
• SYS_RID_ORDER
• TIV_GB
• TIV_SSF
• UNNEST
• USE_TTT_FOR_GSETS

Listing 2: Documented Oracle Hints:


Undocumented Hints:

BYPASS_RECURSIVE_CHECK IGNORE_ON_CLAUSE OVERFLOW_NOMOVE


BYPASS_UJVC IGNORE_WHERE_CLAUSE PIV_GB
CACHE_CB INDEX_RRS PIV_SSF
CACHE_TEMP_TABLE INDEX_SS PQ_MAP
CIV_GB INDEX_SS_ASC PQ_NOMAP
COLLECTIONS_GET_REFS INDEX_SS_DESC REMOTE_MAPPED
CUBE_GB LIKE_EXPAND RESTORE_AS_INTERVALS
CURSOR_SHARING_EXACT LOCAL_INDEXES SAVE_AS_INTERVALS
DEREF_NO_REWRITE MV_MERGE SCN_ASCENDING
DML_UPDATE NESTED_TABLE_GET_REFS SKIP_EXT_OPTIMIZER
DOMAIN_INDEX_NO_SORT NESTED_TABLE_SET_REFS SQLLDR
DOMAIN_INDEX_SORT NESTED_TABLE_SET_SETID SYS_DL_CURSOR
DYNAMIC_SAMPLING NO_EXPAND_GSET_TO_UNION SYS_PARALLEL_TXN
DYNAMIC_SAMPLING_EST_CDN NO_FACT SYS_RID_ORDER
EXPAND_GSET_TO_UNION NO_FILTERING TIV_GB
FORCE_SAMPLE_BLOCK NO_ORDER_ROLLUPS TIV_SSF
GBY_CONC_ROLLUP NO_PRUNE_GSETS UNNEST
GLOBAL_TABLE_HINTS NO_STATS_GSETS USE_TTT_FOR_GSETS
HWM_BROKERED NO_UNNEST
NOCPU_COSTING

Hints

Hints are comments embedded in SQL that can help influnce the behaviour of the Cost Based Optimizer.

Hints are always specified immediately after the first word of a SQL statement. eg.

SELECT /*+ place your hint here*/ column_name ...


FROM table_name

The table below contains:

• Hints for Access Methods


• Hints for Join Orders
• Hints for Join Operations
• Hints for Parallel Execution
• Additional Hints

Hint Purpose Use when...


Hints for Access Methods
FULL(tab) Force a Full Table Scan on tab. Used to stop Oracle from performing an index scan.
ROWID(tab) Force a table access by Rowid on Given an equals condition on a rowid, Oracle will alwayse use it. This hint is used to force a
tab Rowid Range scan on tab.
CLUSTER(tab) Force a cluster scan on tab This would be rare. A cluster scan is pretty good, so Oracle will normally select it
automatically. If it doesn't, this hint will force a cluster scan.
HASH(tab) Force a hash access on tab if tab is Typically an equals predicate on a hash clustered table will always use hash access, unless
hash clustered. the table is very small indeed. This hint may be required if accessing a hash clustered table
via an IN list, or an IN subquery
INDEX(tab [ ind ...]) Force an index scan on table tab Specifying just the table name (or alias) is the preferred method of stopping a Full Table
Scan. If the statistics are calculated against the tables and indexes, Oracle should choose
the best available index. The second form is dangerous, as it assumes the name of the
index to be used will not change. Only use it if there are many indexes and Oracle will not
choose the right one. Better yet, use NO_INDEX to disable the index you want to avoid.
If you supply multiple indexes, Oracle will usually choose the best one from the list
specified. Beware though that you don't fall into the AND-EQUAL trap.
INDEX_COMBINE(tab [ ind ...]) Forces a bitmap index access path Primarily this hint just tells Oracle to use the bitmap indexes on table tab. Otherwise Oracle
on tab will choose the best combination of indexes it can think of based on the statistics. If it is
ignoring a bitmap index that you think would be helpful, you may specify that index plus all
of the others taht you want to be used. Note that this does not force the use of those
indexes, Oracle will still make cost based choices.
INDEX_JOIN(tab [ ind ...]) Use the Index Join technique to All columns in your SQL for a given table are contained in two or more indexes. Oracle can
avoid a table access. merge the indexes to avoid a table lookup. If there are different possible combinations of
indexes that could be used, specify the index names as well if there is a particular
combination that would be faster.
INDEX_DESC(tab [ ind ...]) Same as the INDEX hint, except
process range scans in descending Use this hint if you are using an index to sort rows instead of an ORDER BY.
order
Hint Purpose Use when...
INDEX_FFS(tab [ ind ...]) Forces a Fast Full Scan on one of If all columns required for a SQL reside in one index, then a Fast Full Scan may be used
tab's indexes instead of a Full Table Scan to avoid a table access.
NO_INDEX(tab [ ind ...]) Forces Oracle to ignore indexes Used with just the table name (or alias), Oracle will ignore all indexes on that table. This is
equivalent to a FULL hint unless the table is clustered. If index names are specified, they
will not be used. If Oracle has two indexes to choose from, this could be used to disable an
index, instead of using the INDEX hint to force the use of the other index.
AND_EQUAL(tab ind ind [ ind...]) Forces Oracle to scan all nominated
Don't use this. You will probably never come across a good implementation of this
single column indexes used in AND
technique. See the AND-EQUAL trap.
col = ... predicates
USE_CONCAT Expand OR predicates or IN lists into Each predicate in the list of ORs can individually use and index, and collectively the ORs
UNIONs return less than 4% of the table. Also useful in a join query where each of the OR predicates
is indexed and on a different table.
NO_EXPAND Stops Oracle from expanding ORs If in Explain Plan you see that Oracle is expanding ORs or IN lists into UNIONs, and you
and IN lists into UNIONs. See think a full table scan would be faster because the UNIONs collectively return more than 4%
USE_CONCAT. of the table, then use this hint to check it out.
REWRITE([view ...]) Forces Oracle to resolve the query
Use when the materialized view resolves the same joins or aggregates as are used in the
using a meterialized view instead of
query.
the tables in the FROM clause.
NO_REWRITE Forces Oracle to stop using query Use when the session or database parameter QUERY_REWRITE_ENABLED is set to true,
rewrite. but you want to avoid using the materiazed view because it may be out of date.
Hints for Join Orders
ORDERED Join the tables in the FROM clause Use if Oracle is joining table in the wrong order. Can also be used to encourage Oracle to
in the order they are specified use a non-correlated WHERE col IN sub-query as the driving table in a SELECT and then
join back to the outer table. If you just want to suggest the best table to lead the join, try the
LEADING hint instead.
STAR Forces Oracle to use a star query Avoid using this. Star queries are deprecated in favour of STAR_TRANSFORMATION
plan. which uses bitmap indexes in favour of cartesian joins. See Star Query.
Hints for Join Operations
USE_NL(tab [tab..]) Use a Nested Loops join Use when Oracle is using a Hash or Sort Merge join (high volume SQLs), and you want it to
use a Nested Loops join (low volume SQLs). Older versions of Oracle required this hint to
be used in conjunction with the ORDERED hint. This is still advisable to avoid unexpected
results.
USE_MERGE(tab [tab..]) Use a Sort-Merge join on tab Use when Oracle is using a Nested Loops join, and you have a high volume join using
range predicates. Older versions of Oracle required this hint to be used in conjunction with
Hint Purpose Use when...
the ORDERED hint. This is still advisable to avoid unexpected results.
USE_HASH(tab [tab..]) Use a Hash join on tab Use when Oracle is using a Nested Loops or Merge join, and you have a high volume join
using equals predicates. Older versions of Oracle required this hint to be used in
conjunction with the ORDERED hint. This is still advisable to avoid unexpected results.
DRIVING_SITE(tab) Forces Oracle to evaluate a join
Firstly, try not to join to remote tables. If you must, use this hint when you are joining a local
involving a remote table on the
table to a remote table, and the local table is smaller. See Remote Table.
remote table's database.
LEADING(tab) Use instead of the ORDERED hint if you only want to suggest the best starting table. Oracle
Forces tab to be the leading table in
can have trouble choosing a leading table if there a two of more in the SQL with non-
a join
indexed WHERE clauses.
HASH_AJ Use this when your high volume NOT IN sub-query is using a FILTER or NESTED LOOPS
Use a Hash Anti-Join to evaluate a join. See High Volumne Nested Loops Joins. Check Explain Plan to ensure that it shows
NOT IN sun-query. HASH JOIN (ANTI). Try MERGE_AJ if HASH_AJ refuses to work.
The HASH_AJ hint is sepcified from within the sub-query, not in the main SQL statement.
MERGE_AJ Use a Merge Anti-Join to evaluate a Use this when HASH_AJ does not work. MERGE_AJ will probably not work either, but it's
NOT IN sun-query. worth a try.
HASH_SJ Use this when you have a high volume outer query, and a correlated single table sub-query
with equals joins back to the outer query, and no DISTINCT / GROUP BY clause. Check
Use a Hash Semi-Join to evaluate a
Explain Plan to ensure that it shows HASH JOIN (SEMI). Try MERGE_SJ if HASH_SJ
correlated EXISTS sub-query.
refuses to work.
The HASH_SJ hint is sepcified from within the sub-query, not in the main SQL statement.
MERGE_SJ Use a Merge Semi-Join to evaluate Use this when HASH_SJ does not work. MERGE_SJ will probably not work either, but it's
a correlated EXISTS sub-query. worth a try.
Hints for Parallel Execution
Parallel Query hints have been deliberately omitted because they are a lazy way to tune and wreak havoc for DBAs if over-used. Speak to your DBA about using
parallel query.
Additional Hints
APPEND Use Direct Path data load to append inserted rows to the end of the table, rather than
Direct Path Insert
searching for free space in previously used data blocks.
CACHE Usually Full Table Scans will not bump other blocks out of cache, the theory being that they
Cache blocks from Full Table Scan probably won't be used again. Use this hint if you are going to perform another Full Table
Scan on the same table straight away.
NO_CACHE Do not cache blocks from a Full This is the default behaviour, so you should never need it. Perhaps if the CACHE hint were
Hint Purpose Use when...
hard coded into a view, the NO_CACHE hint on a select from the view would override it.
Table Scan
Just guessing.
MERGE Use when you join to a view that contains a GROUP BY or DISTINCT. See Selecting from
Enables Complex View Merging
Views
NO_MERGE Complex View Merging is a good thing. Don't use this hint unless you are curious to see
Disable Complex View Merging
how much faster complex view merging can be.
UNNEST A global panacea for badly written
sub-queries. Can be used in place of If you can't get your sub-query to stop using a FILTER step, try UNNEST. It uses internal
Anti-joins and Semi-joins if you are cleverness to rewrite your query.
not really sure what you're doing.
NO_UNNEST Forces Oracle not to Unnest sub- If UNEST_SUBQUERY initialisation parameter is set, Oracle will automatically try to unnest
queries. sub-queries. Use this hint to stop it from doing that for a particular sub-query.
PUSH_PRED(view) Push a join predicate between a Use with a Nested Loop join to a view when the view is the outer (2nd) table in the join. The
view (or inline view) and a table into join condition will be pushed into the view, potentially enabling an index use. See Selecting
the view. from Views.
NO_PUSH_PRED(view) Stop Oracle from pushing join
Pushing Join Predicates is a good thing - don't use this hint.
predicates.
PUSH_SUBQ Use this if you have lots of non-indexed predicates, most of which almost always come out
Force Oracle to evaluate sub-query true, and a non-merged sub-query that reduces the number of rows significantly. The
before other non-indexed predicates. performance benefit will only be noticeable over larger data volumes. Over those volumes
you will probably be better off merging the sub-query (see the UNNEST hint).
STAR_TRANSFORMATION Use bitmap indexes for a Star Use this when joining a fact table with bitmap indexes to dimension tables keyed by those
Transformation execution path. bitmap indexed columns. See Star Query.
ORDERED_PREDICATES Execute the non-indexed non-join If one predicate eliminates a row for a query, Oracle does not evaluate the others. If you
predicates in the order in which they order your predicates with the ones most likely to fail first, then this hint can reduce the total
are supplied. number of predicates evaluated. Also see PUSH_SUBQ.

©Copyright 2003

You might also like