问题:请教HINT写法
企业建站必须是能够以充分展现企业形象为主要目的,是企业文化与产品对外扩展宣传的重要窗口,一个合格的网站不仅仅能为公司带来巨大的互联网上的收集和信息发布平台,成都创新互联公司面向各种领域:成都资质代办等成都网站设计、营销型网站解决方案、网站设计等建站排名服务。
我有一个SQL添加如下hint,目的是指定hash_join方式。
select /*+ordered
use_hash(a,b,c,d) */ *
From a,b,c,d
Where ...
其中,
a只与b有关联关系,b只与c有关联关系,b只与c有关联关系,c只与d有关联关系,
数量级:a:1000条, b:100 万条, c:800万条
, d:100万条
执行计划为:
Hash Join
---Hash Join
----- Hash Join
------ a
----- b
----- c
---d
考虑到d表比较小,我能不能做到将d表作为驱动表、而a,b,c关联之后的结果作为prob外表呢,
通过Ordered好像是没有办法控制这样,加了就只能是a作为驱动表装载内存,b作为prob表与之关联,
之后的结果再作为驱动表,以此类推。
用Leading可以吗?请给出语法,谢谢。
解答:
oracle
10g中
hash_join可以通过no_swap_join_inputs/swap_join_inputs来强制控制build表,配合leading或者ordered可以控制多表之前的连接顺序。
比如t1,t2,t3,t4共4张表做hash_join
可以通过ordered+no_swap_join_inputs/swap_join_inputs来实现。
比如
如果想实现
(
T3 hash-join (T1 hash-join T2)) hash-join
T4
t1作为build表和T2做hash_join,然后t3作为build表和t1,t2的结果集作hash_join,在把t3,t1,t2的结果集作build表和t4做hash_join
通过sql可以写为
MYDB@MYDB10G
>select
2 /*+
3 ordered
4 use_hash(t2)
5 use_hash(t3)
6 swap_join_inputs(t3)
7 use_hash(t4)
8 no_swap_join_inputs(t4)
9 */
10 *
from t1,t2,t3,t4
11 where t1.object_id=t2.object_id
12 and
t2.object_name=t3.object_name
13 and t3.owner=t4.owner
14 and
t4.owner='MYDB'
15 /
已用时间: 00: 00:
00.07
执行计划
----------------------------------------------------------
Plan
hash value:
3494725078
-------------------------------------------------------------------------------------
|
Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time
|
-------------------------------------------------------------------------------------
|
0 | SELECT STATEMENT | | 2137 | 801K| | 182 (2)| 00:00:03
|
|* 1 | HASH JOIN | | 2137 | 801K| | 182 (2)|
00:00:03 |
|* 2 | HASH JOIN | | 52 | 14976 | |
167 (2)| 00:00:03 |
|* 3 | TABLE ACCESS FULL | T3 | 40 | 3840 |
| 15 (0)| 00:00:01 |
|* 4 | HASH JOIN | | 11651
| 2184K| 1232K| 151 (1)| 00:00:02 |
| 5 | TABLE ACCESS FULL| T1
| 11651 | 1092K| | 15 (0)| 00:00:01 |
| 6 | TABLE ACCESS
FULL| T2 | 11652 | 1092K| | 15 (0)| 00:00:01 |
|* 7 | TABLE
ACCESS FULL | T4 | 41 | 3936 | | 15 (0)| 00:00:01
|
-------------------------------------------------------------------------------------
Predicate
Information (identified by operation
id):
---------------------------------------------------
1 -
access("T3"."OWNER"="T4"."OWNER")
2 -
access("T2"."OBJECT_NAME"="T3"."OBJECT_NAME")
3 -
filter("T3"."OWNER"='MYDB')
4 -
access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
7 -
filter("T4"."OWNER"='MYDB')
Note
-----
- dynamic sampling used
for this statement
说明:
ordered表示依据from后面写的表的顺序来做联结~
写hints,分开些思路清晰~ ordered后
from t1 ,t2 ,t3 ,t4说明首先使用t1做驱动表来连接t2,如何连接呢?看后面的hint
use_hash(t2)
代表连接t2的方式是hash_join;然后用use_hash(t3)表示连接t3的方式是hash-join,那么谁作build表呢?看后面的swap_join_inputs(t3)代表t3作build表和t1-t2的结果集作连接....依此类推~
标准的hint就应该这么写~
use_hash(x,y,z)这样的写法是不规范,这样只是说出了x,y,z地联接方式
ordered 是陈旧的hints,leading是用来代替ordered的~
leading不要求sql的写法(from后面的顺序不要求),直接可以在leading中定义连接顺序~
leading和ordered不能一起使用,也没必要一起使用~
至于"能不能举个Ordered不能实现而要用Leading的例子",上面已经说了,from后面的不能被修改的情况下可以使用leading.用法google一下,一大堆文档
针对leading使用:
10g中对leading做了加强~
可以直接在后面写多表的连接顺序了,也就是说使用leading不需要from后面的固定顺序了
MYDB@MYDB10G >select
2
/*+
3 leading(t1 t2 t3 t4)
4 use_hash(t2)
5
use_hash(t3)
6 swap_join_inputs(t3)
7 use_hash(t4)
8
no_swap_join_inputs(t4)
9 */ * from t3,t4,t2,t1
10 where
t1.object_id=t2.object_id
11 and t2.object_name=t3.object_name
12 and
t3.owner=t4.owner
13 and t4.owner='MYDB'
14 /
已用时间: 00: 00:
00.01
执行计划
----------------------------------------------------------
Plan
hash value:
3494725078
-----------------------------------------------------------------------------
|
Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
|
-----------------------------------------------------------------------------
|
0 | SELECT STATEMENT | | 2069 | 179K| 57 (4)| 00:00:01
|
|* 1 | HASH JOIN | | 2069 | 179K| 57 (4)| 00:00:01
|
|* 2 | HASH JOIN | | 50 | 3100 | 38 (3)| 00:00:01
|
|* 3 | TABLE ACCESS FULL | T3 | 40 | 1080 | 18 (0)| 00:00:01
|
|* 4 | HASH JOIN | | 82 | 2870 | 20 (5)| 00:00:01
|
| 5 | TABLE ACCESS FULL| T1 | 11584 | 248K| 16 (0)| 00:00:01
|
| 6 | TABLE ACCESS FULL| T2 | 82 | 1066 | 3 (0)| 00:00:01
|
|* 7 | TABLE ACCESS FULL | T4 | 41 | 1107 | 18 (0)| 00:00:01
|
-----------------------------------------------------------------------------
Predicate
Information (identified by operation
id):
---------------------------------------------------
1 -
access("T3"."OWNER"="T4"."OWNER")
2 -
access("T2"."OBJECT_NAME"="T3"."OBJECT_NAME")
3 -
filter("T3"."OWNER"='MYDB')
4 -
access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
7 -
filter("T4"."OWNER"='MYDB')
MYDB@MYDB10G >select
2
/*+
3 ordered
4 use_hash(t2)
5
use_hash(t3)
6 swap_join_inputs(t3)
7 use_hash(t4)
8
no_swap_join_inputs(t4)
9 */ * from t1,t2,t3,t4
10 where
t1.object_id=t2.object_id
11 and t2.object_name=t3.object_name
12 and
t3.owner=t4.owner
13 and t4.owner='MYDB'
14 /
已用时间: 00: 00:
00.00
执行计划
----------------------------------------------------------
Plan
hash value:
3494725078
-----------------------------------------------------------------------------
|
Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
|
-----------------------------------------------------------------------------
|
0 | SELECT STATEMENT | | 2069 | 179K| 57 (4)| 00:00:01
|
|* 1 | HASH JOIN | | 2069 | 179K| 57 (4)| 00:00:01
|
|* 2 | HASH JOIN | | 50 | 3100 | 38 (3)| 00:00:01
|
|* 3 | TABLE ACCESS FULL | T3 | 40 | 1080 | 18 (0)| 00:00:01
|
|* 4 | HASH JOIN | | 82 | 2870 | 20 (5)| 00:00:01
|
| 5 | TABLE ACCESS FULL| T1 | 11584 | 248K| 16 (0)| 00:00:01
|
| 6 | TABLE ACCESS FULL| T2 | 82 | 1066 | 3 (0)| 00:00:01
|
|* 7 | TABLE ACCESS FULL | T4 | 41 | 1107 | 18 (0)| 00:00:01
|
-----------------------------------------------------------------------------
Predicate
Information (identified by operation
id):
---------------------------------------------------
1 -
access("T3"."OWNER"="T4"."OWNER")
2 -
access("T2"."OBJECT_NAME"="T3"."OBJECT_NAME")
3 -
filter("T3"."OWNER"='MYDB')
4 -
access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
7 - filter("T4"."OWNER"='MYDB'
分享文章:oraclehint中ordered和leading原理很好的帖子
文章出自:
http://dzwzjz.com/article/giohdc.html