博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于表联结方法_sort-merge join
阅读量:5944 次
发布时间:2019-06-19

本文共 4097 字,大约阅读时间需要 13 分钟。

在比较经典的表联结方法中,nested loop join和hash join是比较常用的,对于sort-merge join来说,可能略微有些陌生。
在数据库中有一个隐含参数,默认是开启的。
NAME                                                                             VALUE                          ISDEFAULT ISMOD      ISADJ
-------------------------------------------------------------------------------- ------------------------------ --------- ---------- -----
_optimizer_sortmerge_join_enabled                                                TRUE                           TRUE      FALSE      FALSE
因为这种联结方式如果使用不当回消耗大量的系统资源,在一些生产系统中都选择手动禁用这种联结。
这种联结的运行原理想比nested loop join,hash join而言没有驱动表的说法,所以sort-merge join会可能产生大量的随机读。
比如我们有表emp,dept,
查询语句为
select  empno,ename,dname,loc from emp,dept where emp.deptno =dept.deptno
如果采用sort-merge join的时候,就会对emp,dept表进行order by 的操作。
类似下面两个操作
      select empno,ename ,deptno from emp order by deptno;
      select deptno,dname,loc from dept order by deptno;
因为排序后的数据都是有序的,然后对两个子结果集根据deptno进行匹配。
然后选择两端的数据列,根据列的要求筛选数据。
我们先来看一个使用sort-merge join的执行计划,实际中可能需要用到sort-merge join的场景就是 类似
tab1.column1 between tab2.column2 and tab2.column3 这种形式的查询中。
我们可以使用hint ordered或者 use_merge来引导查询走sort-merge join ,简单模拟一下。
使用hint ordered

SQL> select /*+ordered*/  empno,ename,dname,loc from emp,dept where emp.deptno between dept.deptno-10 and dept.deptno+10

  2  /

39 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 667632632

-----------------------------------------------------------------------------

| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |    39 |  1287 |     6  (34)| 00:00:01 |
|   1 |  MERGE JOIN          |      |    39 |  1287 |     6  (34)| 00:00:01 |
|   2 |   SORT JOIN          |      |    14 |   182 |     3  (34)| 00:00:01 |
|   3 |    TABLE ACCESS FULL | EMP  |    14 |   182 |     2   (0)| 00:00:01 |
|*  4 |   FILTER             |      |       |       |            |          |
|*  5 |    SORT JOIN         |      |     4 |    80 |     3  (34)| 00:00:01 |
|   6 |     TABLE ACCESS FULL| DEPT |     4 |    80 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

   4 - filter("EMP"."DEPTNO")

   5 - access(INTERNAL_FUNCTION("EMP"."DEPTNO")>="DEPT"."DEPTNO"-10)
       filter(INTERNAL_FUNCTION("EMP"."DEPTNO")>="DEPT"."DEPTNO"-10)
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
       2210  bytes sent via SQL*Net to client
        541  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
         39  rows processed
可以看到对emp,dept都做了全表扫描,对数据进行了排序,然后对根据deptno对结果集进行了匹配和关联,最后把结果集输出。
也可以使用hint use_merge来实现一样的效果。

SQL> select /*+use_merge(dept,emp)*/ empno,ename,dname,loc from emp,dept where emp.deptno between dept.deptno-10 and dept.deptno+10

  2  /

39 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1726864587

-----------------------------------------------------------------------------

| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |    39 |  1287 |     6  (34)| 00:00:01 |
|   1 |  MERGE JOIN          |      |    39 |  1287 |     6  (34)| 00:00:01 |
|   2 |   SORT JOIN          |      |     4 |    80 |     3  (34)| 00:00:01 |
|   3 |    TABLE ACCESS FULL | DEPT |     4 |    80 |     2   (0)| 00:00:01 |
|*  4 |   FILTER             |      |       |       |            |          |
|*  5 |    SORT JOIN         |      |    14 |   182 |     3  (34)| 00:00:01 |
|   6 |     TABLE ACCESS FULL| EMP  |    14 |   182 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

   4 - filter("EMP"."DEPTNO"    5 - access("EMP"."DEPTNO">="DEPT"."DEPTNO"-10)

       filter("EMP"."DEPTNO">="DEPT"."DEPTNO"-10)
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
       1796  bytes sent via SQL*Net to client
        541  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
         39  rows processed

合并排序的思路和数据结构中的合并排序算法,在数据筛选条件有限或者返回有限数据行的查询比较合适。如果本身表中的数据量很大,做sort-merge join就会耗费大量的cpu资源,临时表空间,相比来说不是很划算,完全可以通过其他的联结方式来实现。

转载地址:http://orqtx.baihongyu.com/

你可能感兴趣的文章
win2008r2下安装sql2008r2初版
查看>>
IBM确定公司未来存储技术发展方向
查看>>
hello
查看>>
使用pt-online-schema-change 修复主从数据表数据不一致
查看>>
读《程序员到底怎么了?-》
查看>>
运维日常:群发邮件营销平台--EDM
查看>>
Linux jobs等前后台运行命令详解
查看>>
PV(page view)
查看>>
宏定义与const的区别
查看>>
java中abstract,interface,final,static的区别
查看>>
网站的线下活动如何组织
查看>>
Mac 常用快捷键
查看>>
阿里云CentOS7安装Oracle11GR2
查看>>
多线程之线程同步
查看>>
图片进行base64编解码方法
查看>>
外链起到引导、推广排名的作用
查看>>
python常用的字串格式化选项
查看>>
Lock wait timeout exceeded; try restarting......
查看>>
Servet映射规范翻译
查看>>
手机APP新“战场” 手机银行APP成了银行业的定时炸弹?
查看>>