12 排序合并连接(SORT MERGE JOIN)--优化主题系列

select * from a,b where a.id<=b.id;这个一般都走排序合并连接

 

排序合并连接(SORTMERGE JOIN)

 

前文提到嵌套循环以及哈希连接,他们都有驱动表概念。排序合并连接没有驱动表一说,两个表/行源是对等关系。排序合并连接原理是先对两个表/行源根据JOIN列进行排序(当然了排序的时候要踢出不符合where条件的列),然后再进行连接。排序合并连接可以处理非等值JOIN。有时候,出现了非等值JOIN,还非得走SORT MERGEJOIN不可。根据排序合并的原理,我们知道排序合并连接其实很耗费资源,因为要对2个表/结果集进行排序,所以一般情况下,CBO是不会选择走SORTMERGE JOIN的,除非有以下情况:

 

排序合并连接是个垃圾下面解释下

 

select * from a, b where a.id>b.id;

A 1000W

B 500W

 

1.使用HINT

2.非等值JOIN

3.有一个表或者2个表都已经排序好了

4.JOIN列有索引,对索引进行INDEXFULL SCAN(请自己复习前文的访问路径)返回有序的结果,再和另外的表进行JOIN

 

INDEX FULL SCAN----TABLE ACCESS BY INDEX ROWID

这种是不是只适合表数据很少 

假如说 1000W 

如果走INDEXFULL SCAN  ----TABLE ACCESS BY INDEX ROWID

INDEX FULL SCAN+TABLE ACCESS BY INDEX ROWID  如果很大  会比全表+排序50

 

下面举个例子(基于SCOTT,Oracle11gR2)

alter session set statistics_level=all;

select ename, job, sal, dname, loc from emp, dept whereemp.deptno = dept.deptno;

select * fromtable(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

12 排序合并连接(SORT MERGE JOIN)--优化主题系列_第1张图片

NL 循环是不是要进行物理IO?

排序合并连接要在内存对比

排序合并连接 

其实要返回数据量小的在上面 

类似驱动表的角色

排序合并连接为什么垃圾?

1. 排序而且2都排序

2. 排序之后要进行类似NL的算法

排序合并是不是要耗费PGA?

 

这两个表访问了几次??ID=2 3这里根据哪个列排序的??deptno

ID=2 3返回多少条记录4条对吧

ID=4这里执行了多少次??4次吧

 

我现在是不是有2个已经排序过的结果集??

第一个排序是不是返回4条结果??

排序查找算法是不是取一条结果跟另外已经排序的结果进行比较4个结果就比较4

这个算法类似NL

 

排序合并连接是不是垃圾又要排序还要类似NL操作

 

假设两个表很大排序的结果太大了比如有100W条记录是不是要找100W次??

排序完了之后还要进行类似NL的算法这个时候CPU果断悲剧

但是这个时候的NL又要比真正的NL要优化因为是在内存中进行的

 

排序合并连接一般看不到很少用数据量少走排序合并连接没问题数据量大 CPU容易100% PGA也满了

 

那为什么有时候必须走排序合并连接呢??

因为条件是非等值的不能走HASH JOIN更不能走NL因为NL不是在内存中进行搜索的需要消耗磁盘I/O

但是排序合并连接是消耗CPU一般来说 I/O消耗CPU消耗更严重


你可能感兴趣的:(SQL,Tuning)