0% found this document useful (0 votes)
28 views

Query Hints

The document provides an overview of various hints in Oracle that can be used to optimize queries by influencing the query execution plan. It lists common hints like FULL, INDEX, NO_INDEX, INDEX_JOIN, INDEX_COMBINE and describes their syntax and usage through examples. The hints covered force full table scans, use of specific indexes, disallowing indexes, merging of indexes and combining bitmap indexes. The document also discusses specifying hints correctly and their scope of effect.

Uploaded by

Maliha Khan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views

Query Hints

The document provides an overview of various hints in Oracle that can be used to optimize queries by influencing the query execution plan. It lists common hints like FULL, INDEX, NO_INDEX, INDEX_JOIN, INDEX_COMBINE and describes their syntax and usage through examples. The hints covered force full table scans, use of specific indexes, disallowing indexes, merging of indexes and combining bitmap indexes. The document also discusses specifying hints correctly and their scope of effect.

Uploaded by

Maliha Khan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 22

======================== Hints at a Glance

====================================

The following table lists each hint discussed in this chapter and the use of the
hint.

Hint Use

FIRST_ROWS Generally force the use of indexes


ALL_ROWS Generally force a full table scan
FULL hint Force a full table scan
INDEX Force the use of an index
NO_INDEX Disallow a specified index from being used
INDEX_JOIN Allow the merging of indexes on a single table
INDEX_ASC Use an index ordered in ascending order
INDEX_DESC Use an index ordered in descending order
INDEX_COMBINE Access multiple bitmap indexes
INDEX_FFS Force fast full scans
ORDERED Specify the driving order of tables
LEADING Specify just the first driving table
NO_EXPAND Help eliminate OR expansion
STAR_TRANSFORMATION Force a star query transform
DRIVING_SITE Process data by driving it from a particular database

USE_MERGE Change how tables are joined internally


PUSH_SUBQ Force the subquery to process earlier
PARALLEL Cause full table scan queries to break query into pieces
and process each piece with a different process
NO_PARALLEL Turn off use of parallel operations in any one given
query
APPEND Append data into new blocks
NOAPPEND Check for free space within current blocks before using new
ones
CACHE Cause a full table scan to be pinned into memory

NOCACHE Cause a table that is specified to be cached at database


level to not get cached when you access it
CLUSTER Force clustering
HASH Force cluster hashing
CURSOR_SHARING_EXACT Override the CURSOR_SHARING setting
QB_NAME Assign a name to a query block

===================================================================================
======
==================================== Specifying a Hint
===========================

If you incorrectly specify a hint in any way, it becomes a comment and is


ignored. . The best way to ensure that a hint has been
correctly specified is to run an EXPLAIN PLAN, or set AUTOTRACE to ON in SQL*Plus
to see if
the hint was used

The basic hint syntax (in this example, it is for


a FULL hint) is shown here:

select /*+ FULL(table) */ column1,�

The table in the preceding code snippet is the table name to perform a full table
scan on, or
the alias for the table if you specified an alias in the FROM clause, as shown
here:

select /*+ FULL(emp) */ empno, ename, deptno


from emp
where deptno = 1;

In this example, if there were an index on the DeptNo column, a full table scan
would be
performed. The hint is not required to be uppercase.

By default, hints only affect the code block in which they appear. If you hint the
access of the
EMP table in a query that is part of a UNION operation, the other queries within
the UNION will
not be affected by your hint. If you want all of the unioned queries to use the
same hint, you will
need to specify the hint in each of the queries.

You can specify the query block name in hints to specify the query block to which
the hint
applies. Thus, in an outer query you can specify a hint that applies to a subquery.
The syntax for
the queryblock argument of the hint syntax is in the form
@queryblock

You can use more than one hint at a time, although this may cause some or all of
the hints to be
ignored. Separate hints with spaces, are shown here:

select /*+ FULL(table) CACHE(table)*/ column1,�

The (table) in this code snippet is the table name to perform the full scan and
cache on.

select /*+ FULL(emp) CACHE(emp)*/ empno, ename, deptno


from emp
where deptno = 1;

====================== When Using an Alias, Hint the Alias, Not the Table
=================================

When you use aliases on a given table that you want to use in a hint, you must
specify the alias
and not the table name in the hint. If you specify the table name in the hint when
an alias is used,
the hint is not used.

select /*+ FULL(table) */ column1,�

The (table) in this code snippet has to be replaced with the alias that follows,
since the query
uses an alias. If an alias is used, the alias must be used in the hint or the hint
will not work.

select /*+ FULL(A) */ empno, ename, deptno


from emp A
where deptno = 1;

====================== Clearing the Cache ================================

The first step is to flush the shared pool to clear the cache of older SQL
statements:

SQL> ALTER SYSTEM FLUSH SHARED_POOL;

===================================== The FIRST_ROWS Hint


====================================

The FIRST_ROWS hint generally forces the use of indexes, which under normal
circumstances may not have been used

The FIRST_ROWS hint is ignored in UPDATE and DELETE statements, since all rows of
the
query must be updated or deleted. It is also ignored when any grouping statement is
used (GROUP
BY, DISTINCT, INTERSECT, MINUS, UNION

Syntax
select /*+ FIRST_ROWS(n) */ column1, �

Example
select /*+ FIRST_ROWS */ empno, ename, deptno
from emp
where deptno = 1;

Example

select /*+ FIRST_ROWS(10) */ empno, ename, deptno


from emp
where deptno = 1;

================================ The ALL_ROWS Hint


=======================================

The ALL_ROWS (best throughput) hint directs a query to optimize a query on the
basis of
retrieving all of the rows the fastest.

Syntax
select /*+ ALL_ROWS */ column1, �

Example

select /*+ ALL_ROWS */ empno, ename, deptno


from emp
where deptno = 1;

======================================= The FULL Hint


========================================

The FULL hint directs a query to override the optimizer and perform a full table
scan on the
specified table in the hint.

Syntax
select /*+ FULL(table) */ column1,�

Here, (table) is the table name to perform the full scan on. If an alias is used,
the alias must be
used in the hint or it will not work.

Note that you should only specify the table name in the hint, not the schema name.
Example

select /*+ FULL(emp) */ empno, ename, deptno


from emp
where deptno = 1;

============================================ The INDEX Hint


========================================

The INDEX hint is frequently used to force one or more indexes to be executed for a
given query.
Oracle generally chooses the correct index or indexes with the optimizer, but when
the optimizer
chooses the wrong index or no index at all, this hint is excellent

Syntax
select /*+ INDEX (table index1, index2�) */ column1, �

Example

select /*+ INDEX (emp deptno_idx) */ empno, ename, deptno


from emp
where deptno = 1;

In this example, the deptno_idx index on the emp table will be used.

Example

select /*+ INDEX (emp deptno_idx, empno_idx) */ empno, ename, deptno


from emp
where deptno = 1
and empno = 7750;

In the second example, Oracle may use the deptno_idx index, or the empno_idx index,
or a
merge of both of them. We have placed these choices in the optimizer�s hands to
decipher the
best choice.

Example

select /*+ INDEX */ empno, ename, deptno


from emp
where deptno = 1
and empno = 7750;

In this example, no index is specified. Oracle now weighs all of the possible
indexes that are
available and chooses one or more to be used

As of Oracle Database 10g, you can specify column names as part of the INDEX hint.
The
columns can be prefixed with the table names (not table aliase

Syntax

select /*+ INDEX ([table.]column1 [[table2.]column2]) */ column1, �

Example

select /*+ INDEX (emp.deptno) */ empno, ename, deptno


from emp
where deptno = 1;

============================================= The NO_INDEX Hint


======================================

The NO_INDEX hint disallows the optimizer from using a specified index. This is a
great hint
for tuning queries with multiple indexes. While you may not know which of multiple
indexes to
drive the query with, you might know which ones that you don�t want the optimizer
to use

Syntax

select /*+ NO_INDEX (table index1, index2�) */ column1, �


Example

select /*+ NO_INDEX (emp deptno_idx) */ ename, deptno


from emp
where deptno = 1;

In this example, the deptno_idx index on the emp table will not be used. If the
NO_INDEX
hint is used and no index is specified, a full table scan will be performed.

If the NO_INDEX and a conflicting hint (such as INDEX) are specified for the same
index, then both hints are ignored
(as in the example that follows).

Example

select /*+ NO_INDEX (emp deptno_idx) INDEX (emp deptno_idx) */ ename, deptno
from emp
where deptno = 1;
========================================= The INDEX_ JOIN Hint
==================================

The INDEX_JOIN hint merges separate indexes from a single table together so that
only the
indexes need to be accessed. This approach saves a trip back to the table.

Syntax

select /*+ INDEX_JOIN (table index1, index2�) */ column1, �

Example

select /*+ index_join(test2 year_idx state_idx) */ state, year


from test2
where year = '1972'
and state = MA;

In this query, the optimizer will merge the year_idx and state_idx indexes and will
not need
to access the test2 table

========================================= The INDEX_COMBINE Hint


=====================================

The INDEX_COMBINE hint is used to specify multiple bitmap indexes when you want the
optimizer to use all indexes that you specify.

You can also use the INDEX_COMBINE hint


to specify single indexes (this is preferred over using the INDEX hint for
bitmaps). For b-tree
indexes, use the INDEX hint instead of this one.

Syntax

select /*+ INDEX_COMBINE (table index1, index2�) */ column1, �

Example

select /*+ INDEX_COMBINE (emp deptno_bidx, mgr_bidx) */ empno, ename, deptno


from emp
where deptno = 1
and mgr = 7698;

======================================= The INDEX_ASC Hint


====================================

The INDEX_ASC hint currently does exactly the same thing as the INDEX hint. Since
indexes are
already scanned in ascending order, this does nothing more than the current INDEX
hint.

Oracle does not guarantee that indexes will be scanned in ascending order in the
future, but this hint will guarantee that an index will be scanned in ascending
order.

Syntax

select /*+ INDEX_ASC (table index1, index2�) */ column1, �

Example

select /*+ INDEX_ASC (emp deptno_idx) */ empno, ename, deptno


from emp
where deptno = 1;

========================================= The INDEX_DESC Hint


=======================================

The INDEX_DESC hint causes indexes to be scanned in descending order (of their
indexed value
or order), which is the opposite of the INDEX and INDEX_ASC hints.

This hint is overridden when the query has multiple tables, because the index needs
to be used in the normal ascending
order to be joined to the other table in the query.

Syntax

select /*+ INDEX_DESC (table index1, index2�) */ column1, �

Example

select /*+ INDEX_DESC (emp deptno_idx) */ empno, ename, deptno


from emp
where deptno = 1;

======================================= The INDEX_FFS Hint


==================================

The INDEX_FFS hint indicates a fast full scan of the index should be performed.
This hint
accesses only the index and not the corresponding table. The fast full scan of the
index will be
used only if all of the information that the query needs to retrieve is in the
index. This hint can
give great performance gains, especially when the table has a large number of
columns.

Syntax

select /*+ INDEX_FFS (table index) */ column1, �

Example

select /*+ INDEX_FFS (emp deptno_idx) */ deptno, empno


from emp
where deptno = 1;

The INDEX_FFS hint will be used only if the deptno_idx index contains both the
deptno and
empno columns as a part of it. The NO_INDEX_FFS has the same syntax, but this hint
tells the
optimizer not to perform fast full index scans of the specified indexes

The INDEX_FFS processes only the index and does not take the result
and access the table. All columns that are used and retrieved by the
query must be contained in the index.\

========================================= The ORDERED Hint


================================

The ORDERED hint causes tables to be accessed in a particular order, based on the
order of the
tables in the FROM clause of the query, which is often referred to as the driving
order for a query.

Before cost-based optimization, the last table in the FROM clause was the driving
table in queries
however, using the ORDERED hint causes the first table in the FROM clause to be the
driver

Syntax

select /*+ ORDERED */ column1, �

Example

select /*+ ORDERED */ empno, ename, dept.deptno


from emp, dept
where emp.deptno = dept.deptno
and dept.deptno = 1
and emp.empno = 7747;

If both tables (emp and dept) have been analyzed (using the cost-based optimizer)
and there
are no indexes on either table, the emp table is accessed first and the dept table
is accessed
second. There are a lot of possible variations (covered in the next two chapters)
that cause this to
work differently.

Example

select /*+ ORDERED */ emp.empno, ename, dept.deptno, itemno


from emp, dept, orders
where emp.deptno = dept.deptno
and emp.empno = orders.empno
and dept.deptno = 1
and emp.empno = 7747
and orders.ordno = 45;

If all three tables (emp, dept, and orders) have been analyzed and there are no
indexes on
any of the tables, the emp table would be accessed first and then joined to the
dept table, which
would be accessed second. The result would be joined with the orders table, which
is accessed
last

========================================= The LEADING Hint


===================================

As the complexity of queries becomes greater, it becomes more difficult to figure


out the order
of all of the tables using the ORDERED hint. You can often figure out which table
should be
accessed first (driving table), but you may not know which table to access after
that one. The
LEADING hint allows you to specify one table to drive the query; the optimizer
figures out which
table to use after that. If you specify more than one table with this hint, it is
ignored. The
ORDERED hint overrides the LEADING hint.

Syntax
select /*+ LEADING (table1) */ column1, �

Example

select /*+ LEADING(DEPT) */ emp.empno, ename, dept.deptno, itemno


from emp, dept, orders
where emp.deptno = dept.deptno
and emp.empno = orders.empno
and dept.deptno = 1
and emp.empno = 7747
and orders.ordno = 45;

If all three tables (emp, dept, and orders) have been analyzed and there are no
indexes on
any of the tables, the DEPT table would be accessed first (driving the query). The
optimizer would
figure out the rest (probably accessing the intersection table EMP next).

=================================== The NO_EXPAND Hint


=======================================

The NO_EXPAND hint is used to keep the optimizer from �going off the deep end� when
it
is evaluating IN-lists that are combined with an OR. It disallows the optimizer
from using OR
expansion. Without the NO_EXPAND hint, the optimizer may create a very long explain
plan.

Syntax

select /*+ NO_EXPAND */ column1, �

Example

select /*+ FIRST_ROWS NO_EXPAND */ col1, col2...


from members
where (memb_key between 205127 and 205226
or memb_key between 205228 and 205327
or memb_key between 205330 and 205429
or memb_key between 205431 and 205530);

I have used the NO_EXPAND hint and was able to get performance that was almost 50
times
faster than without the hint.

Example (Using Oracle�s Sample Schema tables)

select /*+ FIRST_ROWS NO_EXPAND */ product_id, translated_name


from oe.product_descriptions
where language_id = 'US'
and (product_id between 2187 and 2193
or product_id between 2326 and 2330
or product_id between 3176 and 3177
or product_id between 3245 and 3249);

The NO_EXPAND hint prevents the optimizer from using OR


expansion and is used when the query will become substantially
more complex as a result of the expansion.
============================================= The DRIVING_SITE Hint
===============================

The DRIVING_SITE hint is identical to the ORDERED hint, except this hint is for
processing data
by driving it from a particular database. The table specified in the hint will be
the driving site that
will be used to process the actual join.

Syntax

select /*+ DRIVING_SITE (table) */ column1, �

Example

select /*+ DRIVING_SITE (deptremote) */ empno, ename, deptremote.deptno


from emp, dept@oratusc deptremote
where emp.deptno = deptremote.deptno
and deptremote.deptno = 10
and empno = 7747;

Oracle normally would retrieve the rows from the remote site and join them at the
local site
if this hint was not specified. Since the �empno = 7747� limits the query greatly,
we would rather
pass the small number of rows from the emp table to the remote site instead of
pulling an entire
dept table department back to our local site to process.

Limiting the rows that are retrieved from a remote site can also be achieved by
creating a
view locally for the remote table. The local view should have the WHERE clause that
will be
used, so that the view will limit the rows returned from the remote database before
they are sent
back to the local database. I have personally tuned queries from hours to seconds
using this method.

TIP
The DRIVING_SITE hint is extremely powerful, as it will potentially
limit the amount of information that will be processed over your
network. The table specified with the DRIVING_SITE hint will be the
location for the join to be processed

========================================= The USE_MERGE Hint


=====================================
The USE_MERGE hint is a hint that tells the optimizer to use a MERGE JOIN operation
when
performing a join. A MERGE JOIN operation may be useful when queries perform set
operations
on large numbers of rows. Assume you are joining two tables together. In a MERGE
JOIN, the
row set returned from each table is sorted and then merged to form the final result
set. Since each
result is sorted and then merged together, this action is most effective when
retrieving all rows
from a given query. If you wanted the first row faster instead, the USE_NL would be
the hint to
use (to force a nested loops join)

Syntax

select /*+ USE_MERGE (table) */ column1, �

Example

select /*+ USE_MERGE(orders) */ emp.empno, ename, dept.deptno, itemno


from emp, dept, orders
where emp.deptno = dept.deptno
and emp.empno = orders.empno
and dept.deptno = 1
and emp.empno = 7747
and orders.ordno = 45;

The USE_MERGE hint in this query causes the orders table to be joined in a sort-
merge join to the
returned row source resulting from the join of the emp and dept tables

The NO_USE_MERGE hint uses the same syntax but


instructs the optimizer to not use merge joins when selecting execution paths for a
query

TIP
In a join of three or more tables, the USE_MERGE hint causes the
table(s) specified in the hint to be sort-merge joined with the resulting
row set from a join of the other tables in the join.

=========================================== The USE_NL Hint


===================================

The USE_NL (use nested loops) hint is usually the fastest way to return a single
row (response
time); thus, it may be slower at returning all the rows. This hint causes a
statement to be
processed using nested loops, which takes the first matching row from one table
based on the
result from another table. This is the opposite of a merge join, which retrieves
rows that match
the conditions from each table and then merges them together.

Syntax

select /*+ USE_NL (table1, table2,�) */ column1, �

Example

select /*+ ORDERED USE_NL(dept) */ empno, ename, dept.deptno


from emp, dept
where emp.deptno = dept.deptno
and dept.deptno = 1
and emp.empno = 7747;

The USE_NL hint causes the optimizer to take the resulting rows returned from the
emp table
and process them with the matching rows from the dept table (the specified nested
loop table).
The first row that matches from the dept table can be returned to the user
immediately (as in a
web-based application),

The USE_NL hint usually provides the best response time (first row
comes back faster) for smaller result sets; whereas the USE_MERGE
hint usually provides the best throughput when the USE_HASH hint
can�t be used.

The NO_USE_NL hint uses the same syntax, but instructs the optimizer not to use
nested
loops joins, but to use a different join execution plan. A related hint,
USE_NL_WITH_INDEX,
takes two parameters�the name of the inner table for the join along with the name
of the index
to use when performing the join.

========================================= The USE_HASH Hint


======================================

The USE_HASH hint is usually the fastest way to join many rows together from
multiple tables if
you have adequate memory for this operation. The USE_HASH <hint or method> is
similar to the
nested loops where one result of one table is looped through the result from the
joined table.

You
must have a large enough HASH_AREA_SIZE or PGA_AGGREGATE_TARGET for
this to work properly; otherwise, the operation will occur on disk.
Syntax

select /*+ USE_HASH (table1, table2,...) */ column1, �

Example

select /*+ USE_HASH (dept) */ empno, ename, dept.deptno


from emp, dept
where emp.deptno = dept.deptno
and emp.empno = 7747;

The USE_HASH hint causes the optimizer to take the rows returned from the emp table
and
process them with the matching rows from the dept table (the specified hash table),
which are
hashed into memory. The first row that matches from the dept table can be returned
to the user
immediately, as opposed to waiting until all matching rows are found. There are
cases where
the optimizer will override this hint

The NO_USE_HASH hint has a similar syntax but instructs the optimizer to not use
hash joins when
selecting execution paths for a query. The optimizer will instead use other join
methods such
as nested loops or merge joins.

=========================================== The PUSH_SUBQ Hint


=================================

The PUSH_SUBQ hint can lead to dramatic performance gains (an increase of over 100
times in
performance) when used in the appropriate situation

The best situation to use this hint is when


the subquery will return a relatively small number of rows (quickly); those rows
can then be used
to substantially limit the rows in the outer query

This hint cannot be used when the query uses a merge join and cannot
be used with remote tables. Moving the subquery to be part of the main query (when
possible)
can lead to the same gains when the tables are driven in the correct order
(accessing the former
subquery table first).

Syntax

select /*+ PUSH_SUBQ */ column1, �


Example

select /*+ PUSH_SUBQ */ emp.empno, emp.ename, itemno


from emp, orders
where emp.empno = orders.empno
and emp.deptno =
(select deptno
from dept
where loc = 'BELMONT');

This query processes the subquery to be used by the outer query at its earliest
possible time.

====================================== The PARALLEL Hint


=========================================

The PARALLEL hint causes the optimizer to break a query into pieces (the degree of
parallelism)
and process each piece with a different process. The degree of parallelism is
applied to each
parallelizable operation of a SQL statement.

Syntax

/*+ PARALLEL (table, DEGREE) */

The degree is the number of pieces into which the query is broken.

Example

select /*+ PARALLEL (order_line_items) */ invoice_number, invoice_date


from order_line_items
order by invoice_date;

Example

select /*+ PARALLEL (order_line_items, 4) */ invoice_number, invoice_date


from order_line_items
order by invoice_date;

This statement specifies a degree of parallelism of four. Per previous discussion,


as many as
nine query servers may be allocated or created to satisfy this query.

Example

select /*+ PARALLEL (oli, 4) */ invoice_number, invoice_date


from order_line_items oli
order by invoice_date;
============================================ The NO_PARALLEL Hint
===============================

If a table is created with a parallel degree set, the table will use that degree
for all full table scan
queries. However, you may also �turn off� the use of parallel operations in any one
given query
on a table that has been specified to use parallel operations using the NO_PARALLEL
hint.

Syntax

select /*+ NO_PARALLEL (table) */ ...

Example

select /*+ NO_PARALLEL (oli) */ invoice_number, invoice_date


from order_line_items oli
order by invoice_date;

=========================================== The APPEND Hint


====================================

The APPEND hint improves the performance of INSERTs, but with a potential cost in
terms of
space. The APPEND hint does not check to see if there is space within currently
used blocks for
inserts, but instead appends the data into new blocks.

If an INSERT is parallelized using the PARALLEL hint, APPEND will be used by


default. You
can use the NOAPPEND hint (next section) to override this behavior. Also note that
before
you can use this example, you must first enable parallel DML.

Syntax

insert /*+ APPEND */ �

Example

insert /*+ APPEND */


into emp (empno, deptno)
values (7747, 10);
======================================== The NOAPPEND Hint
=====================================

The NOAPPEND hint is used to override the default for the PARALLEL inserts (the
default, of
course, is APPEND). The NOAPPEND hint is the opposite of the APPEND hint and checks
for
free space within current blocks before using new ones.

Syntax

insert /*+ NOAPPEND */ �

Example

insert /*+ PARALLEL(emp) NOAPPEND */


into emp (empno, deptno)
values (7747, 10);

======================================== The CACHE Hint


====================================

The CACHE hint causes a full table scan to be cached (pinned) into memory, so
future users
accessing the same table find it in memory instead of going to disk. This creates
one potentially
large problem. If the table is very large, it is taking up an enormous amount of
memory (data block
buffer cache space in particular). For small lookup tables, however, this is an
excellent option to
use. Tables can be created with the CACHE option to be cached the first time they
are accessed.

Syntax

select /*+ CACHE(table) */ column1, �

Example

select /*+ FULL(dept) CACHE(dept) */ deptno, loc


from dept;

========================================== The NOCACHE Hint


=====================================
The NOCACHE hint causes a table that is specified to be CACHED at the database
level to not
get cached when you access it.

Syntax

select /*+ NOCACHE(table) */ column1, �

Example

alter table dept cache;


select deptno, loc
from dept;

Example

alter table dept cache;


select /*+ NOCACHE(dept) */ deptno, loc
from dept;

In this example, the table is not cached despite the ALTER statement and is put on
the Least
Recently Used (LRU) list.

============================================ The CLUSTER Hint


===============================

The CLUSTER hint is used only for clusters. A cluster is usually created when
tables are joined
so often that it is faster to create an object containing information about the
joined tables that
is accessed most often. A cluster is identical to denormalizing a table or group of
tables. The
CLUSTER hint forces the use of the cluster. If hashing is used for the cluster (see
the next section),
the HASH hint should be considered. I have not had much luck with using clusters
and gaining
performance.

Syntax

select /*+ CLUSTER (table) */ column1, �

===================================== The HASH Hint


========================================
HASH indexes require the use of hash clusters. When a cluster or hash cluster is
created, a cluster
key is defined. The cluster key tells Oracle how to identify the rows stored in the
cluster and where
to store the rows in the cluster. When data is stored, all of the rows relating to
the cluster key are
stored in the same database blocks. With the data being stored in the same database
blocks, using
the hash index, Oracle can access the data by performing one hash function and one
I/O�as
opposed to accessing the data by using a b-tree index.

Syntax

select /*+ HASH(table) */ column1, �

Example

select /*+ HASH(emp) */ empno, dept.deptno


from emp, dept
where emp.deptno = dept.deptno
where empno = 7747;

======================================= The CURSOR_SHARING_EXACT Hint


================================

The CURSOR_SHARING_EXACT hint is used to ensure that literals in SQL statements are
not
replaced with bind variables. This hint can be used to correct any minor issues
when you don�t
want to use cursor sharing even though instance-level CURSOR_SHARING parameter is
set to
either FORCE or SIMILAR.

Syntax

select /*+ CURSOR_SHARING_EXACT */ column1, �

Example

select /*+ CURSOR_SHARING_EXACT */ empno, ename


from emp
where empno = 123;

========================================== The QB_NAME Hint


========================================

The QB_NAME hint is used to assign a name to a query block within a statement. You
can then
assign a hint elsewhere in the statement that references the query block. For
example, if you have
a query that contains a subquery, you can assign a query block name to the subquery
and then
provide the hint at the outermost query level. If two or more query blocks are
given the same
QB_NAME value, the optimizer will ignore the hints

select /*+ FULL(@deptblock dept) */ empno


from emp
where emp.deptno IN
(select /*+ QB_NAME(deptblock) */ dept.deptno
from dept
where loc = 'CHICAGO');

========================================= USE_NL_WITH_INDEX
=============================

USE_NL_WITH_INDEX The USE_NL hint instructs the optimizer to use a nested loops
join with the specified table as the non-driving table (or as the inner table that
is looped
through with the result of the driving table). The USE_NL_WITH_INDEX hint allows
you
to also specify the index that is used during the access. However, the optimizer
must be
able to use that index with at least one join.
Select /*+ USE_NL_WITH_INDEX (table index1, index2,...) */

======================================= INDEX_SS
=================================

INDEX_SS The INDEX_SS hint instructs the optimizer to use the �skip scan� option
for
an index on the specified table. A skip scan is where in a concatenated index
Oracle
skips the first column of the index and uses the rest of the index. This hint works
well
with a two-part concatenated index where you often use both parts but infrequently
need only the second part (at times you don�t have any condition for the first
part). You
need to specify both the table and the index.

Select /*+ INDEX_SS(table index1, index2,..) */

INDEX_SS_ASC The INDEX_SS_ASC hint is the same as the INDEX_SS hint, but this
could change in a future version of Oracle.

INDEX_SS_DESC The INDEX_SS_DESC hint uses the same syntax as the INDEX_SS
hint but instructs the optimizer to scan the index skip scan in descending order.

You might also like