排序合并连接 (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表连接------&gt;排序合并连接(Merge Sort Join)的更多相关文章

  1. oracle 表连接 - sort merge joins 排序合并连接

    https://blog.csdn.net/dataminer_2007/article/details/41907581一. sort merge joins连接(排序合并连接) 原理 指的是两个表 ...

  2. 排序合并连接(sort merge join)的原理

    排序合并连接(sort merge join)的原理 排序合并连接(sort merge join)的原理     排序合并连接(sort merge join)       访问次数:两张表都只会访 ...

  3. SQL Tuning 基础概述06 - 表的关联方式:Nested Loops Join,Merge Sort Join & Hash Join

    nested loops join(嵌套循环)   驱动表返回几条结果集,被驱动表访问多少次,有驱动顺序,无须排序,无任何限制. 驱动表限制条件有索引,被驱动表连接条件有索引. hints:use_n ...

  4. 经典排序算法 - 归并排序Merge sort

    经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 ...

  5. Oracle表连接

    一个普通的语句select * from t1, t2 where t1.id = t2.id and t1.name = 'a'; 这个语句在什么情况下最高效? 表连接分类: 1. 嵌套循环连接(N ...

  6. Oracle 表连接方式分析 .

    一 引言 数据仓库技术是目前已知的比较成熟和被广泛采用的解决方案,用于整和电信运营企业内部所有分散的原始业务数据,并通过便捷有效的数据访问手段,可以支持企业内部不同部门,不同需求,不同层次的用户随时获 ...

  7. oracle 表连接 - hash join 哈希连接

    一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集 ...

  8. Oracle表的几种连接方式

    1,排序 - - 合并连接(Sort Merge Join, SMJ) 2,嵌套循环(Nested Loops, NL) 3,哈希连接(Hash Join, HJ) Join是一种试图将两个表结合在一 ...

  9. Oracle 表三种连接方式(sql优化)

    在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理. 一.连接方式: 嵌套循环(Nested Loops (NL)) (散列)哈希 ...

随机推荐

  1. AJAX同步与异步

    今天来大概说说AJAX中的同步与异步.其实,就我的理解,同步与异步的区别就是程序执行过程中是否有等待. 同步:意思就是js代码加载到当前的 AJAX时候,会等待AJAX代码执行完毕后再开始加载其他代码 ...

  2. 倒计时IE10+

    直接上代码,dome 里边有我做的列表倒计时(多个同时倒计时)下面是我做的例子,颜色可以自己设置的 <p name="daojishi" style="width: ...

  3. 【Hibernate】Illegal attempt to associate a collection with two open sessions

    今天在用Hibernate对对象进行修改操作的时候报了这个错. 之前一直没什么错误,但是今天修改了一下表结构,增加了一个OneToMany的映射. 所以在我获取对象,重新set一个变量之后就报了这个错 ...

  4. G - I Think I Need a Houseboat(简单题,粘贴下来是因为数据精度需要注意)

    These will be floating point numbers:看这句话,就是说数据会是浮点型的, 问题(一)数据定义成double类型就过了 我当时以为定义成float类型就可以了, 因为 ...

  5. 2014 HDU多校弟八场H题 【找规律把】

    看了解题报告,发现看不懂 QAQ 比较简单的解释是这样的: 可以先暴力下达标,然后会发现当前数 和 上一个数 的差值是一个 固定值, 而且等于当前数与i(第i个数)的商, 于是没有规律的部分暴力解决, ...

  6. Pathchirp—有效的带宽估计方法(二)

    上一个blog介绍了有效带宽估计方法:pathload.http://blog.csdn.net/ice110956/article/details/11126491. 做一个小小的总结:pathlo ...

  7. 红黑树和AVL树的实现与比较-----算法导论

    一.问题描述 实现3种树中的两种:红黑树,AVL树,Treap树 二.算法原理 (1)红黑树 红黑树是一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是red或black.红黑树满足以 ...

  8. windows下各个浏览器用html5进行h.264大视频播放的性能对比说明

    最近在调查windows下哪种浏览器进行大视频播放时候稳定性比较高. 举h.264的4g的视频为例. 选用的浏览器有ie10,firefox,chrome.(因为opera不支持h.264所以没有考虑 ...

  9. The connection to adb is down, and a severe error has occured.问题解决

    遇到问题描述: 运行android程序控制台输出 [2013-06-25 11:10:32 - MyWellnessTracker] The connection to adb is down, an ...

  10. Eclipse下执行main函数报java.lang.NoClassDefFoundError的解决

    今天执行eclipse下的一个java类,无论run还是debug,都报java.lang.NoClassDefFoundError.而且把main中函数都注释掉,执行还是报一样的错. 检查了一下这个 ...