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 ...
The table below contains:
|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 tab||Given an equals condition on a rowid, Oracle will alwayse use it. This hint is used to force a 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 hash clustered.||Typically an equals predicate on a hash clustered table will always use hash access, unless 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 on tab||Primarily this hint just tells Oracle to use the bitmap indexes on table tab. Otherwise Oracle 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 avoid a table access.||All columns in your SQL for a given table are contained in two or more indexes. Oracle can 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 order||Use this hint if you are using an index to sort rows instead of an ORDER BY.|
|INDEX_FFS(tab [ ind ...])||Forces a Fast Full Scan on one of tab's indexes||If all columns required for a SQL reside in one index, then a Fast Full Scan may be used 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 single column indexes used in AND col = ... predicates||Don't use this. You will probably never come across a good implementation of this technique. See the AND-EQUAL trap.|
|USE_CONCAT||Expand OR predicates or IN lists into UNIONs||Each predicate in the list of ORs can individually use and index, and collectively the ORs 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 and IN lists into UNIONs. See USE_CONCAT.||If in Explain Plan you see that Oracle is expanding ORs or IN lists into UNIONs, and you think a full table scan would be faster because the UNIONs collectively return more than 4% of the table, then use this hint to check it out.|
|REWRITE([view ...])||Forces Oracle to resolve the query using a meterialized view instead of the tables in the FROM clause.||Use when the materialized view resolves the same joins or aggregates as are used in the query.|
|NO_REWRITE||Forces Oracle to stop using query rewrite.||Use when the session or database parameter QUERY_REWRITE_ENABLED is set to true, 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 in the order they are specified||Use if Oracle is joining table in the wrong order. Can also be used to encourage Oracle to 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 plan.||Avoid using this. Star queries are deprecated in favour of STAR_TRANSFORMATION 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 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 involving a remote table on the remote table's database.||Firstly, try not to join to remote tables. If you must, use this hint when you are joining a local table to a remote table, and the local table is smaller. See Remote Table.|
|LEADING(tab)||Forces tab to be the leading table in a join||Use instead of the ORDERED hint if you only want to suggest the best starting table. Oracle can have trouble choosing a leading table if there a two of more in the SQL with non-indexed WHERE clauses.|
|HASH_AJ||Use a Hash Anti-Join to evaluate a NOT IN sun-query.||Use this when your high volume NOT IN sub-query is using a FILTER or NESTED LOOPS join. See High Volumne Nested Loops Joins. Check Explain Plan to ensure that it shows 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 NOT IN sun-query.||Use this when HASH_AJ does not work. MERGE_AJ will probably not work either, but it's worth a try.|
|HASH_SJ||Use a Hash Semi-Join to evaluate a correlated EXISTS sub-query.||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 Explain Plan to ensure that it shows HASH JOIN (SEMI). Try MERGE_SJ if HASH_SJ 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 a correlated EXISTS sub-query.||Use this when HASH_SJ does not work. MERGE_SJ will probably not work either, but it's 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.|
|APPEND||Direct Path Insert||Use Direct Path data load to append inserted rows to the end of the table, rather than searching for free space in previously used data blocks.|
|CACHE||Cache blocks from Full Table Scan||Usually Full Table Scans will not bump other blocks out of cache, the theory being that they 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 Table Scan||This is the default behaviour, so you should never need it. Perhaps if the CACHE hint were hard coded into a view, the NO_CACHE hint on a select from the view would override it. Just guessing.|
|MERGE||Enables Complex View Merging||Use when you join to a view that contains a GROUP BY or DISTINCT. See Selecting from Views|
|NO_MERGE||Disable Complex View Merging||Complex View Merging is a good thing. Don't use this hint unless you are curious to see how much faster complex view merging can be.||UNNEST||A global panacea for badly written sub-queries. Can be used in place of Anti-joins and Semi-joins if you are not really sure what you're doing.||If you can't get your sub-query to stop using a FILTER step, try UNNEST. It uses internal cleverness to rewrite your query.||NO_UNNEST||Forces Oracle not to Unnest sub-queries.||If UNEST_SUBQUERY initialisation parameter is set, Oracle will automatically try to unnest 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 view (or inline view) and a table into the view.||Use with a Nested Loop join to a view when the view is the outer (2nd) table in the join. The join condition will be pushed into the view, potentially enabling an index use. See Selecting from Views.||NO_PUSH_PRED(view)||Stop Oracle from pushing join predicates.||Pushing Join Predicates is a good thing - don't use this hint.||PUSH_SUBQ||Force Oracle to evaluate sub-query before other non-indexed predicates.||Use this if you have lots of non-indexed predicates, most of which almost always come out true, and a non-merged sub-query that reduces the number of rows significantly. The 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 Transformation execution path.||Use this when joining a fact table with bitmap indexes to dimension tables keyed by those bitmap indexed columns. See Star Query.||ORDERED_PREDICATES||Execute the non-indexed non-join predicates in the order in which they are supplied.||If one predicate eliminates a row for a query, Oracle does not evaluate the others. If you order your predicates with the ones most likely to fail first, then this hint can reduce the total number of predicates evaluated. Also see PUSH_SUBQ.|