oracle表连接------>排序合并连接(Merge Sort Join)
排序合并连接 (Sort Merge Join)是一种两个表在做连接时用排序操作(Sort)和合并操作(Merge)来得到连接结果集的连接方法。
对于排序合并连接的优缺点及适用场景例如以下:
a,通常情况下。排序合并连接的运行效率远不如哈希连接,但前者的使用范围更广。由于哈希连接仅仅能用于等值连接条件,而排序合并连接还能用于其它连接条件(如<,<=,>.>=)
b,通常情况下。排序合并连接并不适合OLTP类型的系统。其本质原因是对于由于OLTP类型系统而言,排序是很昂贵的操作,当然,假设能避免排序操作就例外了。
oracle表之间的连接之排序合并连接(Merge Sort Join),其特点例如以下:
1,驱动表和被驱动表都是最多仅仅被訪问一次。
2,排序合并连接的表无驱动顺序。
3,排序合并连接的表须要排序,用到SORT_AREA_SIZE。
4,排序合并连接不适用于的连接条件是:不等于<>。like,当中大于>,小于<,大于等于>=,小于等于<=,是能够适用于排序合并连接
5。排序合并连接,假设有索引就能够排除排序。
以下我来做个实验来证实如上的结论:
详细的測试基础表请查看本人Blog 例如以下链接:
oracle表连接之----〉嵌套循环(Nested Loops Join)
1。驱动表和被驱动表的訪问次数:
SQL> select /*+ ordered use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id;
SQL> select sql_id, child_number, sql_text from v$sql where sql_text like '%use_merge%';
SQL_ID CHILD_NUMBER SQL_TEXT
------------- ------------ --------------------------------------------------------------------------------
85u4h9hfqa5ar 0 select sql_id, child_number, sql_text from v$sql where sql_text like '%use_merg
6xph9fhapys39 0 select /*+ ordered use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id
SQL> select * from table(dbms_xplan.display_cursor('6xph9fhapys39',0,'allstats last'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 6xph9fhapys39, child number 0
-------------------------------------
select /*+ ordered use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id
Plan hash value: 412793182
--------------------------------------------------------------------------------
| Id | Operation | Name |
Starts | E-Rows | A-Rows | A-Time | Buf
--------------------------------------------------------------------------------
| 1 | MERGE JOIN | | 1 | 100 | 100 |00:00:00.07 |
| 2 | SORT JOIN | | 1 | 100 | 100 |00:00:00.01 |
| 3 | TABLE ACCESS FULL| T1 | 1 | 100 | 100 |00:00:00.01 |
|* 4 | SORT JOIN | | 100 | 100K| 100 |00:00:00.07 |
| 5 | TABLE ACCESS FULL| T2 | 1 | 100K| 100K|00:00:00.01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."ID"="T2"."T1_ID")
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
filter("T1"."ID"="T2"."T1_ID")
Note
-----
- dynamic sampling used for this statement
26 rows selected
从上面的实验能够看出排序合并连接和HASH连接时一样的。T1和T2 表都仅仅会被訪问0次或者1次。
select /*+ ordered use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id and 1=2;此语句T1和T2表就会是被訪问0次。
自己能够做试验測试下。
总结:排序合并连接根本就没有驱动和被驱动表的概念,而嵌套循环连接和哈希连接就要考虑驱动和被驱动表的情况。!
2,排序合并的表的驱动顺序
以下是T1为驱动表的运行计划
select /*+ leading(t1) use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id and t1.num=20;
select sql_id,child_number,sql_text from v$sql where sql_text like '%from t1,t2 where t1.id=t2.t1_id and t1.num=20%';
SQL> select * from table(dbms_xplan.display_cursor('8z4jvhnnfhxyf',0,'allstats last'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 8z4jvhnnfhxyf, child number 0
-------------------------------------
select /*+ leading(t1) use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id and t1.num=20
Plan hash value: 412793182
-----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
| 1 | MERGE JOIN | | 1 | 1 | 1 |00:00:00.58 | 3462 | | | |
| 2 | SORT JOIN | | 1 | 1 | 1 |00:00:00.01 | 6 | 2048 | 2048 |2048
(0)|
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|* 3 | TABLE ACCESS FULL| T1 | 1 | 1 | 1 |00:00:00.01 | 6 | | | |
|* 4 | SORT JOIN | | 1 | 100K| 1 |00:00:00.58 | 3456 | 14M| 1490K| 12M
(0)|
| 5 | TABLE ACCESS FULL| T2 | 1 | 100K| 100K|00:00:00.01 | 3456 | | | |
-----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("T1"."NUM"=20)
4 - access("T1"."ID"="T2"."T1_ID")
filter("T1"."ID"="T2"."T1_ID")
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
23 rows selected.
Elapsed: 00:00:00.01
以下是T2为驱动表的运行计划:
SQL> select * from table(dbms_xplan.display_cursor('bxydvw58bhczf',0,'allstats last'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID bxydvw58bhczf, child number 0
-------------------------------------
select /*+ leading(t2) use_merge(t1)*/ * from t1,t2 where t1.id=t2.t1_id and t1.num=20
Plan hash value: 1792967693
-----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
| 1 | MERGE JOIN | | 1 | 1 | 1 |00:00:02.20 | 3462 | | | |
| 2 | SORT JOIN | | 1 | 100K| 21 |00:00:02.20 | 3456 | 14M| 1490K| 12M
(0)|
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 3 | TABLE ACCESS FULL| T2 | 1 | 100K| 100K|00:00:00.10 | 3456 | | | |
|* 4 | SORT JOIN | | 21 | 1 | 1 |00:00:00.01 | 6 | 2048 | 2048 |2048
(0)|
|* 5 | TABLE ACCESS FULL| T1 | 1 | 1 | 1 |00:00:00.01 | 6 | | | |
-----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."ID"="T2"."T1_ID")
filter("T1"."ID"="T2"."T1_ID")
5 - filter("T1"."NUM"=20)
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
23 rows selected.
Elapsed: 00:00:00.85
从上面的两个运行计划能够看出,不管T1表示驱动表还是被驱动表,效果都是一样的,排序的尺寸一个是2048+12M,一个是12M+2048。
结论:排序合并连接没有驱动的概念。不管哪个表再前面都无所谓。
3,排序合并连接的限制
SQL〉explain plan for select /*+ leading(t1) use_merge(t2)*/ * from t1,t2 where t1.id<>t2.t1_id and t1.num=20;
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 4016936828
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5000 | 1083K| 82709 (1)| 00:15:10 |
| 1 | NESTED LOOPS | | 5000 | 1083K| 82709 (1)| 00:15:10 |
| 2 | TABLE ACCESS FULL| T2 | 100K| 10M| 710 (1)| 00:00:08 |
|* 3 | TABLE ACCESS FULL| T1 | 1 | 107 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("T1"."NUM"=20 AND TO_CHAR("T1"."ID") LIKE
TO_CHAR("T2"."T1_ID"))
16 rows selected.
从上面的运行计划能够看出,优化器走的是NESTED LOOPS JOIN。
SQL> explain plan for select /*+ leading(t1) use_merge(t2)*/ * from t1,t2 where t1.id>t2.t1_id and t1.num=20;
Explained.
Elapsed: 00:00:00.01
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 412793182
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5000 | 1083K| | 5080 (1)| 00:00:56 |
| 1 | MERGE JOIN | | 5000 | 1083K| | 5080 (1)| 00:00:56 |
| 2 | SORT JOIN | | 1 | 107 | | 4 (25)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| T1 | 1 | 107 | | 3 (0)| 00:00:01 |
|* 4 | SORT JOIN | | 100K| 10M| 25M| 5076 (1)| 00:00:56 |
| 5 | TABLE ACCESS FULL| T2 | 100K| 10M| | 710 (1)| 00:00:08 |
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("T1"."NUM"=20)
4 - access(INTERNAL_FUNCTION("T1"."ID")>INTERNAL_FUNCTION("T2"."T1_ID"))
filter(INTERNAL_FUNCTION("T1"."ID")>INTERNAL_FUNCTION("T2"."T1_ID"))
19 rows selected.
同理能够实验得出:排序合并连接不适用于的连接条件是:不等于<>,like,当中大于>,小于<。大于等于>=,小于等于<=,是能够适用于排序合并连接
oracle表连接------>排序合并连接(Merge Sort Join)的更多相关文章
- oracle 表连接 - sort merge joins 排序合并连接
https://blog.csdn.net/dataminer_2007/article/details/41907581一. sort merge joins连接(排序合并连接) 原理 指的是两个表 ...
- 排序合并连接(sort merge join)的原理
排序合并连接(sort merge join)的原理 排序合并连接(sort merge join)的原理 排序合并连接(sort merge join) 访问次数:两张表都只会访 ...
- SQL Tuning 基础概述06 - 表的关联方式:Nested Loops Join,Merge Sort Join & Hash Join
nested loops join(嵌套循环) 驱动表返回几条结果集,被驱动表访问多少次,有驱动顺序,无须排序,无任何限制. 驱动表限制条件有索引,被驱动表连接条件有索引. hints:use_n ...
- 经典排序算法 - 归并排序Merge sort
经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 ...
- Oracle表连接
一个普通的语句select * from t1, t2 where t1.id = t2.id and t1.name = 'a'; 这个语句在什么情况下最高效? 表连接分类: 1. 嵌套循环连接(N ...
- Oracle 表连接方式分析 .
一 引言 数据仓库技术是目前已知的比较成熟和被广泛采用的解决方案,用于整和电信运营企业内部所有分散的原始业务数据,并通过便捷有效的数据访问手段,可以支持企业内部不同部门,不同需求,不同层次的用户随时获 ...
- oracle 表连接 - hash join 哈希连接
一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集 ...
- Oracle表的几种连接方式
1,排序 - - 合并连接(Sort Merge Join, SMJ) 2,嵌套循环(Nested Loops, NL) 3,哈希连接(Hash Join, HJ) Join是一种试图将两个表结合在一 ...
- Oracle 表三种连接方式(sql优化)
在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理. 一.连接方式: 嵌套循环(Nested Loops (NL)) (散列)哈希 ...
随机推荐
- JQ 一些基本方法
1.判断复选框是否有选中,bischecked 返回 ture 或 false var bischecked = $('[name=uid]').is(':checked'); 2.查看当前元素是父元 ...
- BZOJ 3384: [Usaco2004 Nov]Apple Catching 接苹果( dp )
dp dp( x , k ) = max( dp( x - 1 , k - 1 ) + *** , dp( x - 1 , k ) + *** ) *** = 0 or 1 ,根据情况 (BZOJ 1 ...
- u-boot分析——struct gd_t与struct bd_t
gd_t和bd_t是u-boot中两个重要的数据结构,在初始化操作很多都要靠这两个数据结构来保存或传递.分别定义在./include/asm/global_data.h和./include/asm/u ...
- 基于visual Studio2013解决算法导论之042单源最短路径
题目 单源最短路径 解决代码及点评 // 26单源最短路径bellmanford.cpp : 定义控制台应用程序的入口点. // #include <iostream> #incl ...
- http 连接复用
定义 Http/1.0每次请求都需要建立新的TCP连接,连接不能复用.Http/1.1新的请求可以在上次建立的tcp连接之上发送,连接可以复用. 优点 减少重复进行tcp三次握手的开销,提高效率.注意 ...
- Storm 配置图文解析
Storm 配置图文解析 參考阅读:http://www.xiaofateng.com/? p=959 ============================== | sample-topology ...
- Android的BUG(一) - HTML 5 播放streaming video造成卡住的问题
这个bug,是google自带的问题. 和见到的诸多android的疑难问题一样,这又是一个可以归类为 多线程同步/状态机 问题. 问题处在NuPlayer的异步消息的handle中,现象和原因不细说 ...
- Android跟蓝牙耳机建立连接有两种方式
Android 跟蓝牙耳机建立连接有两种方式. 1. Android 主动跟蓝牙耳机连BluetoothSettings 中和蓝牙耳机配对上之后, BluetoothHeadsetService 会收 ...
- 基于JSP+SERVLET的新闻发布系统(三)
拖了这么久..今天把栏目管理还有新闻管理模块的也挂出来.. 栏目管理跟用户管理一样. 这里重点讲解新闻管理. 效果图如上: 1,可选择栏目类别,且栏目类别是动态生成的. 默认生成的文章是未审核状态的. ...
- c语言中float、double、long double在内存中存储方式
存储格式中的二机制转为浮点数: 浮点型变量在计算机内存中占用4个字节(4 Byte),即32-bit,一个浮点数由2部分组成:底数m 和 指数e: 底数部分:使用2进制数来表示此浮点数的实际值: 指 ...