SWAP_JOIN_INPUTS Oracle Hint(处理hash join强制大表(segment_size大)作为被驱动表)
SWAP_JOIN_INPUTS Oracle Hint(处理hash join强制大表(segment_size大)作为被驱动表)
swap_join_inputs是针对哈希连接的hint,它的含义是让优化器交换原哈希连接的驱动表和被驱动表的顺序,即在依然走哈希连接的情况下让原哈希连接的驱动表变被驱动表,让原哈希连接的被驱动表变为驱动表。
注意,在swap_join_inputs hint中指定的目标表应该是原哈希连接中的被驱动表,否则oracle会忽略该hint。
/*+ swap_join_inputs(原哈希连接的被驱动表) */
其使用范例如下:
|
1
2
|
select /*+ leading(dept) use_hash(emp) swap_join_intputs(emp) */ * from emp,dept whereemp.deptno=dept.deptno |
测试案例:
|
1
2
3
4
5
6
|
SCOTT@ORA12C> create table t1 as select * from dba_objects where rownum<2;Table created.SCOTT@ORA12C> create table t2 as select * from dba_objects where rownum<12;Table created.SCOTT@ORA12C> create table t3 as select * from dba_objects where rownum<22;Table created. |
收集统计信息:
|
1
2
3
4
5
6
|
SCOTT@ORA12C> exec dbms_stats.gather_table_stats(ownname => 'SCOTT',tabname => 'T1',estimate_percent => 100,cascade => true,method_opt => 'for all columns size 1',no_invalidate => false);PL/SQL procedure successfully completed.SCOTT@ORA12C> exec dbms_stats.gather_table_stats(ownname => 'SCOTT',tabname => 'T2',estimate_percent => 100,cascade => true,method_opt => 'for all columns size 1',no_invalidate => false);PL/SQL procedure successfully completed.SCOTT@ORA12C> exec dbms_stats.gather_table_stats(ownname => 'SCOTT',tabname => 'T3',estimate_percent => 100,cascade => true,method_opt => 'for all columns size 1',no_invalidate => false);PL/SQL procedure successfully completed. |
3个表的记录如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
SCOTT@ORA12C> select count(*) from t1; COUNT(*)-----------------11 row selected.SCOTT@ORA12C> select count(*) from t2; COUNT(*)----------------- 111 row selected.SCOTT@ORA12C> select count(*) from t3; COUNT(*)----------------- 211 row selected. |
现在我们来让表T2和T3做哈希连接,由于T3表的记录数比T2表的记录数多,所以这里指定T3为哈希连接的被驱动表:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
select /*+ ordered use_hash(t3) */ t2.object_name,t3.object_type 2 from t2,t3 where t2.object_id=t3.object_id;Execution Plan----------------------------------------------------------Plan hash value: 1730954469---------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |---------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 11 | 220 |6 (0)| 00:00:01 ||* 1 | HASH JOIN | | 11 | 220 |6 (0)| 00:00:01 || 2 | TABLE ACCESS FULL| T2 | 11 | 110 |3 (0)| 00:00:01 || 3 | TABLE ACCESS FULL| T3 | 21 | 210 |3 (0)| 00:00:01 |---------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID") |
可以看到,上述SQL的执行计划现在走的是哈希连接,并且被驱动表示表T3.
如果我们想让哈希连接的被驱动表由T3变成T2,可以在上述sql加入swap_join_inputs hint:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
select /*+ ordered use_hash(t3) swap_join_inputs(t3) */ t2.object_name,t3.object_type 2 from t2,t3 where t2.object_id=t3.object_id;Execution Plan----------------------------------------------------------Plan hash value: 1723280936---------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |---------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 11 | 220 |6 (0)| 00:00:01 ||* 1 | HASH JOIN | | 11 | 220 |6 (0)| 00:00:01 || 2 | TABLE ACCESS FULL| T3 | 21 | 210 |3 (0)| 00:00:01 || 3 | TABLE ACCESS FULL| T2 | 11 | 110 |3 (0)| 00:00:01 |---------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID") |
用leading(t3) use_hash(t2)也可以同样达到目的:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
select /*+ leading(t3) use_hash(t2) */ t2.object_name,t3.object_type 2 from t2,t3 where t2.object_id=t3.object_id;Execution Plan----------------------------------------------------------Plan hash value: 1723280936---------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |---------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 11 | 220 |6 (0)| 00:00:01 ||* 1 | HASH JOIN | | 11 | 220 |6 (0)| 00:00:01 || 2 | TABLE ACCESS FULL| T3 | 21 | 210 |3 (0)| 00:00:01 || 3 | TABLE ACCESS FULL| T2 | 11 | 110 |3 (0)| 00:00:01 |---------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID") |
由此可见在两个表关联的时候,可以用其他hint代替swap_join_inputs来达到相同的目的:
那么多表关联呢:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
select /*+ ordered use_hash(t3) */ t1.owner,t2.object_name,t3.object_type 2 from t2,t3,t1 where t2.object_id=t3.object_id and t1.object_type=t3.object_type;Execution Plan----------------------------------------------------------Plan hash value: 98820498----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 4 | 120 | 9 (0)| 00:00:01 ||* 1 | HASH JOIN | | 4 | 120 | 9 (0)| 00:00:01 ||* 2 | HASH JOIN | |11 | 220 | 6 (0)| 00:00:01 || 3 | TABLE ACCESS FULL| T2 |11 | 110 | 3 (0)| 00:00:01 || 4 | TABLE ACCESS FULL| T3 |21 | 210 | 3 (0)| 00:00:01 || 5 | TABLE ACCESS FULL | T1 | 1 |10 | 3 (0)| 00:00:01 |----------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - access("T1"."OBJECT_TYPE"="T3"."OBJECT_TYPE") 2 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID" |
可以看到,现在上述sql的执行计划是先由表T2和表T3做哈希连接,然后将他们做哈希连接的连接结果集再和表T1做一次哈希连接。
表T1的记录数为1,表T2的记录数为11,表T3的记录数为21,所以当表的T2和T3做哈希连接时,记录数多的表T3应该是被驱动表,这是因为我们在上述sql中使用了ordered hint和use_hash HINT指定表T3作为表T2和T3连接的时的被驱动表,所以oracle这里选择了表T2和T3做哈希连接,并且选择了表T3作为该哈希连接的被驱动表,这是没有问题的,现在问题在于表T1的记录数仅为1,所以当表T2和T3做哈希连接的结果再和表T1做哈希连接时,表T1应该是驱动表,而不是在上述执行计划里显示的那样作为第二个哈希连接的被驱动表。
使用下面HINT:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
select /*+ ordered use_hash(t3) */ t1.owner,t2.object_name,t3.object_type 2 from t1,t2,t3 where t2.object_id=t3.object_id and t1.object_type=t3.object_type;Execution Plan----------------------------------------------------------Plan hash value: 38266800------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 4 | 120 | 9 (0)| 00:00:01 ||* 1 | HASH JOIN | | 4 | 120 | 9 (0)| 00:00:01 || 2 | MERGE JOIN CARTESIAN| | 11 | 220 | 6 (0)| 00:00:01 || 3 | TABLE ACCESS FULL | T1 | 1 | 10 | 3 (0)| 00:00:01 || 4 | BUFFER SORT | | 11 | 110 | 3 (0)| 00:00:01 || 5 | TABLE ACCESS FULL | T2 | 11 | 110 | 3 (0)| 00:00:01 || 6 | TABLE ACCESS FULL | T3 | 21 | 210 | 3 (0)| 00:00:01 |------------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID" AND "T1"."OBJECT_TYPE"="T3"."OBJECT_TYPE") |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
select /*+ leading(t1) use_hash(t3) */ t1.owner,t2.object_name,t3.object_type 2 from t1,t2,t3 where t2.object_id=t3.object_id and t1.object_type=t3.object_type;Execution Plan----------------------------------------------------------Plan hash value: 2308542799----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 7 | 210 | 9 (0)| 00:00:01 ||* 1 | HASH JOIN | | 7 | 210 | 9 (0)| 00:00:01 ||* 2 | HASH JOIN | | 7 | 140 | 6 (0)| 00:00:01 || 3 | TABLE ACCESS FULL| T1 | 1 |10 | 3 (0)| 00:00:01 || 4 | TABLE ACCESS FULL| T3 |21 | 210 | 3 (0)| 00:00:01 || 5 | TABLE ACCESS FULL | T2 |11 | 110 | 3 (0)| 00:00:01 |----------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID") 2 - access("T1"."OBJECT_TYPE"="T3"."OBJECT_TYPE") |
加入以下hint,就解决:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
SELECT /*+ ordered use_hash(t3) swap_join_inputs(t1) */ t1.owner, t2.object_name, t3.object_type FROM t2, t3, t1 WHERE t2.object_id = t3.object_id 5 AND t1.object_type = t3.object_type;Execution Plan----------------------------------------------------------Plan hash value: 3071514789----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 4 | 120 | 9 (0)| 00:00:01 ||* 1 | HASH JOIN | | 4 | 120 | 9 (0)| 00:00:01 || 2 | TABLE ACCESS FULL | T1 | 1 |10 | 3 (0)| 00:00:01 ||* 3 | HASH JOIN | |11 | 220 | 6 (0)| 00:00:01 || 4 | TABLE ACCESS FULL| T2 |11 | 110 | 3 (0)| 00:00:01 || 5 | TABLE ACCESS FULL| T3 |21 | 210 | 3 (0)| 00:00:01 |----------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - access("T1"."OBJECT_TYPE"="T3"."OBJECT_TYPE") 3 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID") |
转:http://7642644.blog.51cto.com/7632644/1699902
SWAP_JOIN_INPUTS Oracle Hint(处理hash join强制大表(segment_size大)作为被驱动表)的更多相关文章
- Bullet:关于ORACLE中的HASH JOIN的参数变化
Oracle在7.3引入了hash join. 但是在Oracle 10g及其以后的Oracle数据库版本中,优化器,实际是CBO,也是因为HASH JOIN仅适用于CBO,在解析目标SQL时是否考虑 ...
- Oracle 三种连接方式 NESTED LOOP HASH JOIN SORT MERGE JOIN
NESTED LOOP: 对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择.在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大( ...
- oracle多表连接方式Hash Join Nested Loop Join Merge Join
在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理. 一.连接方式: 嵌套循环(Nested Loops (NL) ...
- OLAP 大表和小表并行hash join
一个表50MB 一个表10GB 50M表做驱动表,放在PGA里 这时候慢在对对 10g 的全表扫描 对10个G扫描块 需要开并行 我有这样一个算法 一个进程 读 50mb 8进程 来 扫描 10gb ...
- oracle 表连接 - hash join 哈希连接
一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集 ...
- 品味性能之道<十>:Oracle Hint
Hint 是Oracle 提供的一种SQL语法,它允许用户在SQL语句中插入相关的语法,从而影响SQL的执行方式. 因为Hint的特殊作用,所以对于开发人员不应该在代码中使用它,Hint 更像是Ora ...
- Oracle hint之ORDERED和USE_NL
Hint:ORDERED和USE_NL ORDERED好理解,就是表示根据 from 后面表的顺序join,从左到右,左边的表做驱动表 use_nl(t1,t2):表示对表t1.t2关联时采用嵌套循环 ...
- NESTED LOOPS & HASH JOIN & SORT MERGE JOIN
表连接方式及使用场合 NESTED LOOP 对于被连接的数据子集较小的情况,nested loop连接是个较好的选择.nested loop就是扫描一个表,每读到一条记录,就根据索引去另一个表里面查 ...
- Sql优化(一) Merge Join vs. Hash Join vs. Nested Loop
原创文章,首发自本人个人博客站点,转载请务必注明出自http://www.jasongj.com Nested Loop,Hash Join,Merge Join介绍 Nested Loop: 对于被 ...
随机推荐
- 读书笔记--Android Gradle权威指南(上)
本篇文章已授权微信公众号 dasu_Android(大苏)独家发布 最近看了一本书<Android Gradle 权威指南>,对于 Gradle 理解又更深了,但不想过段时间就又忘光了,所 ...
- angular 获取ng-repeat完成状态 $last
$index $first $middle $last $odd $even html <ul> <li ng-repeat="item in data" rep ...
- 自定义mvc或mtv框架:基于wsgiref的web框架
把mvc或mtv框架的model数据库,view:html,control逻辑处理,url判别,wsgiref集中在一个文件 代码如下 #!/usr/bin/env python #-*- codin ...
- 用js实现超链接导航菜单点击切换选中时的状态
项目中使用到点解导航切换不同的颜色,如果只是li选项卡还好办,这次用到的超链接选项卡,因为a链接每次点击都会刷新,所以浏览器记不住点击的状态,也没法切换点击状态,因为项目中有好多地方要用到,在网上找了 ...
- Windows下git设置代理服务器
SVN中,使用TortoiseSVN来进行版本控制时,设置代理非常简单,只需要在设置里面添加代理的信息即可.而 git 在GUI(v0.17.GITGUI)中却无法找到类似的设置,只能求助 git b ...
- 系统调用syscall---用户态切换到内核态的唯一途径
1.应用程序有时需要内核协助完成一些处理,但是应用程序不可能执行内核代码(主要是安全性考虑), 那么,应用程序需要有一种机制告诉内核,它现在需要内核的帮助,这个机制就是系统调用. 2.系统调用的本质是 ...
- Android为TV端助力 转载:Android绘图Canvas十八般武器之Shader详解及实战篇(下)
LinearGradient 线性渐变渲染器 LinearGradient中文翻译过来就是线性渐变的意思.线性渐变通俗来讲就是给起点设置一个颜色值如#faf84d,终点设置一个颜色值如#CC423C, ...
- leetcode-83.删除排序链表中的重复元素
leetcode-83.删除排序链表中的重复元素 Points 链表 题意 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2 输出: 1- ...
- 前端 CSS预处理器Less
引文 Less是一种动态的样式语言.Less扩展了CSS的动态行为,比如说,设置变量(Variables).混合书写模式(Mixins).操作(Operations)和功能(Functions)等等, ...
- [20190219]那个更快(11g).txt
[20190219]那个更快(11g).txt --//前几天测试11g Query Result Cache RC Latches时,链接http://blog.itpub.net/267265/v ...