Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, amit.

Asked: December 19, 2004 - 10:11 pm UTC

Last updated: April 03, 2012 - 6:36 am UTC

Version: 9.2.0.5

Viewed 50K+ times! This question is

You Asked

Hi,
From the documentation

"The LEADING hint specifies the set of tables to be used as the prefix in the execution plan. "

What does this statement mean by "prefix in the execution plan"

Could you please clarify

thanks

and Tom said...

the driving tables, the first tables accessed.

when you join t1 to t2 to t3 to t4 we could go

t3 -> t4 -> t2 -> t1
t1 -> t2 -> t3 -> t4
t4 -> t3 -> t2 -> t1

and so on -- leading says "use this table to start the join chain"


ops$tkyte@ORA9IR2> create table t1 ( x int, y int );

Table created.

ops$tkyte@ORA9IR2> create table t2 ( x int, y int );

Table created.

ops$tkyte@ORA9IR2> create table t3 ( x int, y int );

Table created.

ops$tkyte@ORA9IR2> create table t4 ( x int, y int );

Table created.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> set autotrace traceonly explain
ops$tkyte@ORA9IR2> select /*+ leading( t3 ) */ *
2 from t1, t2, t3, t4
3 where t1.x = t2.y
4 and t2.x = t3.y
5 and t3.x = t4.y
6 /

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=11 Card=82 Bytes=8528)
1 0 HASH JOIN (Cost=11 Card=82 Bytes=8528)
2 1 HASH JOIN (Cost=8 Card=82 Bytes=6396)
3 2 HASH JOIN (Cost=5 Card=82 Bytes=4264)
4 3 TABLE ACCESS (FULL) OF 'T3' (Cost=2 Card=82 Bytes=2132)
5 3 TABLE ACCESS (FULL) OF 'T2' (Cost=2 Card=82 Bytes=2132)
6 2 TABLE ACCESS (FULL) OF 'T1' (Cost=2 Card=82 Bytes=2132)
7 1 TABLE ACCESS (FULL) OF 'T4' (Cost=2 Card=82 Bytes=2132)

Here we said "start with t3", So Oracle is going to drive with T3, join it to T2, join that to T1 and then join all of that with T4...


ops$tkyte@ORA9IR2> select /*+ leading( t4 ) */ *
2 from t1, t2, t3, t4
3 where t1.x = t2.y
4 and t2.x = t3.y
5 and t3.x = t4.y
6 /

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=11 Card=82 Bytes=8528)
1 0 HASH JOIN (Cost=11 Card=82 Bytes=8528)
2 1 HASH JOIN (Cost=8 Card=82 Bytes=6396)
3 2 HASH JOIN (Cost=5 Card=82 Bytes=4264)
4 3 TABLE ACCESS (FULL) OF 'T4' (Cost=2 Card=82 Bytes=2132)
5 3 TABLE ACCESS (FULL) OF 'T3' (Cost=2 Card=82 Bytes=2132)
6 2 TABLE ACCESS (FULL) OF 'T2' (Cost=2 Card=82 Bytes=2132)
7 1 TABLE ACCESS (FULL) OF 'T1' (Cost=2 Card=82 Bytes=2132)



ops$tkyte@ORA9IR2> set autotrace off

Now we said to start with T4, and Oracle goes T4 to T3 to T2 to T1....


Rating

  (7 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

more clarification

amit, December 20, 2004 - 7:50 am UTC

So /*+ Leading(T4) */
would mean optimizer would start the join chain with t4, but rest of the sequence would be decided by the optimizer based on the costs, Correct ?



Tom Kyte
December 20, 2004 - 8:54 am UTC

correct.

very cool in 10g

Connor, December 20, 2004 - 11:47 pm UTC

leading(t1 t2 t3 t4)

very nice indeed

Clarification

Srikanth Sathya, November 30, 2007 - 11:56 am UTC

Tom

Is the statement "It is not possible to specify more than one table name in the LEAD() hint" true, unlike what the previous user has stated.

Ex. /*+ LEADING( t1 t2 t3) */

Thanks for your time.

Tom Kyte
November 30, 2007 - 2:04 pm UTC

http://docs.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm#sthref1625

it is multi-table, which seems to be what the previous poster (connor) was saying?

A reader, December 06, 2007 - 11:38 am UTC

Can the multi table LEADING hint be accomplished by using ORDERED hint by giving tables after FROM clause in the right way you want ?
Tom Kyte
December 10, 2007 - 10:23 am UTC

well, you have to be "careful" with the ordered hint... subquery un-nesting and the like can have an effect on that (your from list might not be the from list the optimizer optimizes).

In general, I'd say "no" to hinting at all.

leading hint ignored

A reader, April 02, 2012 - 1:34 pm UTC

Hi Tom,

Could you please let me know why LEADING hint is ignored in the below case?

select /*+ DRIVING_SITE(tab1) LEADING(tab1) */ from table@db_link1 tab1, table2@db_link1 tab2 where <conditions>;

When I am running the query(without the dblinks) in target site itself it's using the leading hint. But when I run above query in remote site it's not using the leading hint at all.

Database version: 11.2.0.2

Thanks for your help.
Tom Kyte
April 03, 2012 - 6:36 am UTC

what is the SQL you see in the shared pool on the remote server?

and why do you believe you need the leading hint? are the estimated cardinalities incorrect in the plan on the remote site?


If I issue a query such as:

ops$tkyte%ORA11GR2> create table t1 as select * from all_objects;

Table created.

ops$tkyte%ORA11GR2> create table t2 as select * from all_users;

Table created.

ops$tkyte%ORA11GR2> exec dbms_stats.gather_table_stats( user, 'T1' );

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> exec dbms_stats.gather_table_stats( user, 'T2' );

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> 
ops$tkyte%ORA11GR2> select /*+ driving_site( tab1 ) leading( tab1 ) */  *
  2    from t1@loopback@ora11gr2 tab1, t2@loopback@ora11gr2 tab2
  3   where tab1.owner = tab2.username
  4     and tab2.user_id < 0
  5  /

no rows selected


I see this query in my shared pool:

SELECT /*+ LEADING ("A2") */ "A2"."OWNER","A2"."OBJECT_NAME","A2"."SUBOBJECT_NA
ME","A2"."OBJECT_ID","A2"."DATA_OBJECT_ID","A2"."OBJECT_TYPE","A2"."CREATED","A
2"."LAST_DDL_TIME","A2"."TIMESTAMP","A2"."STATUS","A2"."TEMPORARY","A2"."GENERA
TED","A2"."SECONDARY","A2"."NAMESPACE","A2"."EDITION_NAME","A1"."USERNAME","A1"
."USER_ID","A1"."CREATED" FROM "T1" "A2","T2" "A1" WHERE "A2"."OWNER"="A1"."USE
RNAME" AND "A1"."USER_ID"<0


which shows the remote query was hinted and if the leading hint 'made sense', it would be used.

suggest you check out the remote query and get the plan of it to verify as step one.

Joe, January 29, 2015 - 8:29 pm UTC

Is there anyway to prove a LEADING hint has been used or ignored. Optimiser dump etc. I have used one on a complex query, the first time the query is exzecuted it is driven by the hinted table, the second execution creates another plan that uses the hinted table second.

Arun

arun, July 15, 2015 - 9:33 am UTC

Thanks for the explanation

More to Explore

Performance

Get all the information about database performance in the Database Performance guide.