How to switch the driving table in a hash join [ID 171940.1]
2012-02-23 11:05
411 查看
How to switch the driving table in a hash join [ID 171940.1]
--------------------------------------------------------------------------------
修改时间 13-JUL-2006 类型 BULLETIN 状态 PUBLISHED
*************************************************************
This article is being delivered in Draft form and may contain
errors. Please use the MetaLink "Feedback" button to advise
Oracle of any issues related to this article.
*************************************************************
PURPOSE
-------
Sometimes it may be difficult to get a particular table to drive a query.
This article shows a specific example of switching the driving table in a
hash join
SCOPE & APPLICATION
-------------------
This article provides background information for analysts wishing to tune
queries.
Using the SWAP_JOIN_INPUTS hint to switch the driving table in a hash join
--------------------------------------------------------------------------
Consider the following SQL statement:
SELECT *
FROM emp, dept, dual
WHERE emp.deptno = dept.deptno AND dept.dname = dual.dummy;
(Obviously this query makes no sense, it is just used for illustration).
A typical plan this generates is:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=17 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=17 Card=28588 Bytes=1486576)
2 1 HASH JOIN (Cost=5 Card=14 Bytes=700)
3 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
4 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
5 1 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
In other words the query joins EMP and DEPT using a hash join and then joins to
DUAL using another hash join. If, for performance reasons, a different plan is
desired that drives from the DUAL table, such as:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=17 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=17 Card=28588 Bytes=1486576)
2 1 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
3 1 HASH JOIN (Cost=5 Card=14 Bytes=700)
4 3 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
5 3 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
Then there may be issues generating it.
The problem with achieving this plan is that the Hash Join between EMP and
DEPT cannot be directly referenced in a hint - it has no alias.
The way to achieve the above plan is to use the SWAP_JOIN_INPUTS hint as
shown below:
SQL> set autotrace trace explain
SQL>
SQL> SELECT /*+ ORDERED USE_HASH(dept) SWAP_JOIN_INPUTS(dual) */ *
2 FROM emp, dept, dual
3 WHERE emp.deptno = dept.deptno AND dept.dname = dual.dummy
4 /
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=17 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=17 Card=28588 Bytes=1486576)
2 1 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
3 1 HASH JOIN (Cost=5 Card=14 Bytes=700)
4 3 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
5 3 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
The hint says:
o ORDERED: Use the join order emp - dept - dual, use a
o USE_HASH(dept): Use a hash join with DEPT as the inner table
o SWAP_JOIN_INPUTS(dual): Swap the join inputs involving DUAL
Reference note Note:29236
And thus resutls in the desired plan.
Additional Information
======================
The following are a number of other hints that could be attempted to achieve
the same result (and failed):
Ordered hint:
=============
Here the desired DUAL, (EMP DEPT) join order is specified and hash joins
suggested. However because there is no join between dual and emp in the query,
this results in a cartesian product.
SQL> SELECT /*+ ordered use_hash(dept) */ *
2 FROM dual,emp,dept
3 WHERE emp.deptno = dept.deptno AND dept.dname = dual.dummy
4 ;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=16352 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=16352 Card=28588 Bytes=1486576)
2 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
3 1 MERGE JOIN (CARTESIAN) (Cost=16347 Card=114352 Bytes=3887968)
4 3 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
5 3 BUFFER (SORT) (Cost=16336 Card=14 Bytes=448)
6 5 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
Leading hint:
=============
Thie hint contains a Leading hint on DUAL to force that table to be accessed
first in the join order, then hash hints on the tables to. DUAL is accessed
first but this is then joined to DEPT and the result set joined to EMP, so the
access path is not the same.
SQL> SELECT /*+ leading(dual) use_hash(dept) use_hash(emp) use_hash(dual) */ *
2 FROM dual, dept, emp
3 WHERE emp.deptno = dept.deptno AND dept.dname = dual.dummy
4 ;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=21 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=21 Card=28588 Bytes=1486576)
2 1 HASH JOIN (Cost=15 Card=8168 Bytes=163360)
3 2 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
4 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
5 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
The author acknowledges that there may well be some other method of achieving
this join order and method combination. The SWAP_JOIN_INPUTS hint is one
way of achieving this.
NOTE
====
The SWAP_JOIN_INPUTS hint can be overridden by setting <Event:10103>.
For example:
SQL> alter session set events '10103 trace name context forever, level 1';
Session altered.
SQL> select /*+ ordered use_hash(dept) swap_join_inputs(dual) use_hash(dual) */ *
2 from emp,dept,dual
3 where emp.deptno = dept.deptno and dept.dname = dual.dummy
4 ;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=17 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=17 Card=28588 Bytes=1486576)
2 1 HASH JOIN (Cost=5 Card=14 Bytes=700)
3 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
4 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
5 1 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
How to process the examples
-------------------------------------------------------
- Create the sample database with the scott user Note:100078.1
- run analyze on the 'scott' schema or the objects involved Note:1011835.102).
- set the hash_joined_enabled = true in init<sid>.ora
from:metalink [ID 171940.1]
--------------------------------------------------------------------------------
修改时间 13-JUL-2006 类型 BULLETIN 状态 PUBLISHED
*************************************************************
This article is being delivered in Draft form and may contain
errors. Please use the MetaLink "Feedback" button to advise
Oracle of any issues related to this article.
*************************************************************
PURPOSE
-------
Sometimes it may be difficult to get a particular table to drive a query.
This article shows a specific example of switching the driving table in a
hash join
SCOPE & APPLICATION
-------------------
This article provides background information for analysts wishing to tune
queries.
Using the SWAP_JOIN_INPUTS hint to switch the driving table in a hash join
--------------------------------------------------------------------------
Consider the following SQL statement:
SELECT *
FROM emp, dept, dual
WHERE emp.deptno = dept.deptno AND dept.dname = dual.dummy;
(Obviously this query makes no sense, it is just used for illustration).
A typical plan this generates is:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=17 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=17 Card=28588 Bytes=1486576)
2 1 HASH JOIN (Cost=5 Card=14 Bytes=700)
3 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
4 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
5 1 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
In other words the query joins EMP and DEPT using a hash join and then joins to
DUAL using another hash join. If, for performance reasons, a different plan is
desired that drives from the DUAL table, such as:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=17 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=17 Card=28588 Bytes=1486576)
2 1 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
3 1 HASH JOIN (Cost=5 Card=14 Bytes=700)
4 3 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
5 3 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
Then there may be issues generating it.
The problem with achieving this plan is that the Hash Join between EMP and
DEPT cannot be directly referenced in a hint - it has no alias.
The way to achieve the above plan is to use the SWAP_JOIN_INPUTS hint as
shown below:
SQL> set autotrace trace explain
SQL>
SQL> SELECT /*+ ORDERED USE_HASH(dept) SWAP_JOIN_INPUTS(dual) */ *
2 FROM emp, dept, dual
3 WHERE emp.deptno = dept.deptno AND dept.dname = dual.dummy
4 /
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=17 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=17 Card=28588 Bytes=1486576)
2 1 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
3 1 HASH JOIN (Cost=5 Card=14 Bytes=700)
4 3 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
5 3 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
The hint says:
o ORDERED: Use the join order emp - dept - dual, use a
o USE_HASH(dept): Use a hash join with DEPT as the inner table
o SWAP_JOIN_INPUTS(dual): Swap the join inputs involving DUAL
Reference note Note:29236
And thus resutls in the desired plan.
Additional Information
======================
The following are a number of other hints that could be attempted to achieve
the same result (and failed):
Ordered hint:
=============
Here the desired DUAL, (EMP DEPT) join order is specified and hash joins
suggested. However because there is no join between dual and emp in the query,
this results in a cartesian product.
SQL> SELECT /*+ ordered use_hash(dept) */ *
2 FROM dual,emp,dept
3 WHERE emp.deptno = dept.deptno AND dept.dname = dual.dummy
4 ;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=16352 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=16352 Card=28588 Bytes=1486576)
2 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
3 1 MERGE JOIN (CARTESIAN) (Cost=16347 Card=114352 Bytes=3887968)
4 3 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
5 3 BUFFER (SORT) (Cost=16336 Card=14 Bytes=448)
6 5 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
Leading hint:
=============
Thie hint contains a Leading hint on DUAL to force that table to be accessed
first in the join order, then hash hints on the tables to. DUAL is accessed
first but this is then joined to DEPT and the result set joined to EMP, so the
access path is not the same.
SQL> SELECT /*+ leading(dual) use_hash(dept) use_hash(emp) use_hash(dual) */ *
2 FROM dual, dept, emp
3 WHERE emp.deptno = dept.deptno AND dept.dname = dual.dummy
4 ;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=21 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=21 Card=28588 Bytes=1486576)
2 1 HASH JOIN (Cost=15 Card=8168 Bytes=163360)
3 2 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
4 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
5 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
The author acknowledges that there may well be some other method of achieving
this join order and method combination. The SWAP_JOIN_INPUTS hint is one
way of achieving this.
NOTE
====
The SWAP_JOIN_INPUTS hint can be overridden by setting <Event:10103>.
For example:
SQL> alter session set events '10103 trace name context forever, level 1';
Session altered.
SQL> select /*+ ordered use_hash(dept) swap_join_inputs(dual) use_hash(dual) */ *
2 from emp,dept,dual
3 where emp.deptno = dept.deptno and dept.dname = dual.dummy
4 ;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=17 Card=28588 Bytes=1486576)
1 0 HASH JOIN (Cost=17 Card=28588 Bytes=1486576)
2 1 HASH JOIN (Cost=5 Card=14 Bytes=700)
3 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448)
4 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
5 1 TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=8168 Bytes=16336)
How to process the examples
-------------------------------------------------------
- Create the sample database with the scott user Note:100078.1
- run analyze on the 'scott' schema or the objects involved Note:1011835.102).
- set the hash_joined_enabled = true in init<sid>.ora
from:metalink [ID 171940.1]
相关文章推荐
- How to Switch the Driving Table in a Hash Join (文档 ID 171940.1)
- How To contain multiple fileds in the querystrig, DataNavigateUrlFormatString=xxx.asp?ID={0}&Name={1}
- How-to find the SQL that using lots of temp tablespace in Oracle
- How to Get the Frequency Table of a Categorical Variable as a Data Frame in R
- How to create a task in the openwrt system, the timer to switch WiFi power。
- How To Change the Supplier Bank Account Masking in UI (Doc ID 877074.1)
- How To Turn Up Logging on the Siebel Web Server Extension in Siebel Versions 7.x and 8.x? [ID 477185
- How to collect the full path name of the files in ASM diskgroups (文档 ID 888943.1)
- How To Trace The Remote File Server (RFS) Process In Physical Standby Database (Doc ID 1481125.1)
- How to get the mapping relationship between two columns in a table
- R12: How to add Microsoft Excel as Type to the Create Template List of Values in BI Publisher (Doc ID 1343225.1)
- How to calculate the MD5 hash of a large file in C?
- How to Interpret the "SQL ordered by Physical Reads (UnOptimized)" Section in AWR (文档 ID 1466035.1)
- Weblogic Server in the Chinese show how to solve the problem hash
- 3.You need to extract details of those products in the SALES table where the PROD_ID column contains
- 转:How to submit the rows of a repeating table in InfoPath to a SharePoint list
- How to adjust the high watermark in ORACLE 10g -- ALTER TABLE SHRINK
- How to get the Current Controller Name, Action, or ID in ASP.NET MVC
- Understanding Object Ownership in sql 2000(how to change the schema table name in sql 2000)