How to switch the driving table in a hash join [ID 171940.1]
来源:互联网 发布:网络直播的弊端 编辑:程序博客网 时间:2024/04/28 04:14
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]
- How to switch the driving table in a hash join [ID 171940.1]
- How to Switch the Driving Table in a Hash Join (文档 ID 171940.1)
- How to create a task in the openwrt system, the timer to switch WiFi power。
- 转:How to submit the rows of a repeating table in InfoPath to a SharePoint list
- How To Change the Partition Column Of A Partitioned Table Using DBMS_Redefinition [ID 846405.1]
- How To Change the Partition Column Of A Partitioned Table Using DBMS_Redefinition [ID 846405.1]
- How to search a table in a store proc and open the store proc
- How to Get the Frequency Table of a Categorical Variable as a Data Frame in R
- How to calculate the MD5 hash of a large file in C?
- How to Pin a Cursor in the Shared Pool using DBMS_SHARED_POOL.KEEP (文档 ID 726780.1)
- How to Partition a Non-partitioned Table [ID 1070693.6]
- How to Partition a Non-partitioned Table [ID 1070693.6]
- How to Partition a Non-partitioned Table [ID 1070693.6]
- Show how to print a table in a html page
- MySQL How to add a column in a table?
- How to allow a user to click on TextBlocks which return an integer ID in the click handler
- Index hint ignored for driving table of Outer Join[ID 316518.1]
- How To Determine Table/View Name in a Form
- 行为模式---之观察者设计模式
- 按照时间删除文件的脚本
- 转载一个人对gluPerspective和gluLookAt的初学,想想当初自己……
- Emacs 23.2 自带的Cedet的使用
- Revit 二次开发 - 访问链接文件
- How to switch the driving table in a hash join [ID 171940.1]
- CSS选择器
- android 安卓系统
- Java虚拟机内存的堆区(heap),栈区(stack)和静态区(static/method)
- 千万别惹程序员
- 三级医生查房制度
- hdu 2072 单词数统计 sscanf() 函数
- Spring JDBC
- 今天开始把自己做Legacy BIOS 的心得 和将要做EFI BIOS 的过程和大家分享哈