PLSQL_性能优化系列02_Oracle Join关联
2014-09-25 Created By BaoXinjian
Oracle三种主要连接方式的比较
1. Hash Join
(1).概述
i. 读取一个表的资料,并将放置到内存中,并建立唯一关键字的位图索引
ii. 读取另一个表,和内存中表通过Hash算法进行比较
(2).适用对象
i. 大表连接小表
ii. 两个大表
2. Nested Loops
(1).概述
i. 循环外表记录
ii. 进行逐个比对和内标的连接是否符合条件
(2).适用对象
小表驱动大表,返回较少的结果集
3. Merge Join
(1).概述
i. 两个表进行table access full
ii. 对table access full的结果进行排序
iii. 进行merge join对排序结构进行合并
(2).适用对象
通过rowid访问数据
当sql访问多个表时,关联对sql效率就有很重要的影响。关联要考虑两个因素,join的类型和join的次序。
1. Nested Loop Join方式
1.1 适用条件
(1). 关联少量数据(rows),返回集小。
(2). 关联条件能高效访问第二张表(inner table)。高效访问的关联条件如'=',反之非高效的关联条件如'!=','>'等;inner table(即非驱动表)上要有索引。
因此比较适合OLTP系统,因为OLTP系统中一般返回数据量小,而且表上面索引较多。
1.2 实现步骤
(1). 优化器选择驱动表(driving table),指定其为outer table
(2). 指定另一张表为inner table(非驱动表)
(3). 根据outer table的每行记录的关联字段,来访问inner table。如下所示:
NESTED LOOPS
Outer_Loop
Inner_Loop
由于Nested Loop从outer table向inner table查询,关联的次序就比较重要了。
1.3 Nexted Loop Join的例子
2. Hash Join方式
2.1 适用条件
(1). 仅用于等值关联equijoin(如=);
(2). 满足下列任一条件:
大表关联
或者小表的大部分记录参与关联
2.2 实现机制
(1). 优化器选择较小的表,基于join key构建hash table。(驱动表)
(2). 扫描另外一张较大的表,并在hash table中搜寻关联行
如果内存足够,小表全部在内存中,这种情况是最优的,成本可估算为两张表各一次全表读。
如果内存不够,则小表的一部分可以放在temporary tablespace中(Temp表空间应足够大),以尽可能提高io速度。
2.3 Hash Join的例子
3. Sort merge join
3.1 适用情况
通常情况下hash join性能更好,但如果关联的数据已经排序或不需排序,则sort merge join性能会更好。
非等值关联(nonequi join,如<,> )时很有用,因为sort merge join在返回集很大时比nested loop性能好,而hash join又只能在equijoin中使用。
3.2 实现机制
(1). Sort操作:关联数据按照关联字段进行排序。如果数据本来就是排序的,就不需此操作
(2). Merge操作:经过排序的数据进行merge操作。
需要说明的是,sort merge join没有driving table的概念
4. 笛卡尔连接
无关联条件,应尽可能避免。
5. Outer Join
5.1 Simple Join的扩展
customers表称为preserved table,orders表称为optional table
5.2 Outer Join的扩展
- Left outer join
- Right outer join
- Full outer join
5.3 和普通join相比,outer join也可以是nested loop、hash join、sort merge等。但有一些不同之处:
1. Nested Loop Outer Join中,以preserved table作为驱动表,而不是像普通join基于cost来选择驱动表。
2. Full Outer Join(equijoin)在11g中,自动使用基于hash join的算法。执行计划中出现HASH JOIN FULL OUTER。
可以用HINT:NATIVE_FULL_OUTER_JOIN/NO_NATIVE_FULL_OUTER_JOIN来指定使用或不使用这一算法。
如果不使用,则Full Outer Jion的执行计划是Left Outer Join和Right Outer Jion的Union。
基本原则是:记录少的先关联,这样参与后续关联的记录数就会少。具体来说:
(1). 选择能排除掉最多记录的表作为driving table
(2). 剩余的表中,选选择有最好的filter的表(排除最多记录)作为首先参与关联的表
(3). 以此类推
看这个例子:
SELECT info
FROM taba a, tabb b, tabc c
WHERE a.acol BETWEEN 100 AND 200
AND b.bcol BETWEEN 10000 AND 20000
AND c.ccol BETWEEN 10000 AND 20000
AND a.key1 = b.key1
AND a.key2 = c.key2;
假设a表经过filter后记录最少,b次之,c记录最多。那么可以用a作为driving table,先与b关联,最后与c关联
1. 使用hint指定关联方式
Oracle优化器自动选择join的方式,但有时不是最优的,开发人员可使用hint来选择join方式,比较执行效率。
相关的hint有:
- USE_NL,USE_HASH,USE_MERGE
- Exists子句中,HASH_SJ,MERGE_SJ,NL_SJ
- Not in子句中,HASH_AJ,MERGE_AJ,NL_AJ
2. 使用hint指定关联次序
如果oracle优化器选择的关联次序不是你所希望的,可以用hint(leading和ordered)来指定。Ordered表示按照sql语句中表出现的先后次序,leading则可任意指定,更为通用。
Leading指定了driving table的选定次序。(在nested loop中,driving table就是outer table,在hash join中,是hash table。)
SELECT /*+ leading (a b c) */info
WHERE a.acol BETWEEN 100 AND 200
AND b.bcol BETWEEN 10000 AND 20000
AND c.ccol BETWEEN 10000 AND 20000
AND a.key1 = b.key1
AND a.key2 = c.key2;
3. Undocumented hint参数:swap_join_inputs
注意,上面例子中,a作为驱动表和b关联,关联结果作为驱动表,再和c关联。有时需要改变次序,如下面例子
SELECT /*+ leading (a b c)*/ info
WHERE a.key1 = b.key1
AND b.key2 = c.key2;
假如a 1000条,b 10万条,c 1万条。由于a和c表没有关联字段,因此a和b先关联,再和c关联。但a关联b产生2万条记录,和c关联时,希望以c为驱动表,能否实现呢?
在hash_join中可以用oracle的隐含hint参数swap_join_inputs实现:
SELECT /*+ leading (a b c) swap_join_inputs(c) */ info
WHERE a.key1 = b.key1
AND b.key2 = c.key2;
Thanks and Regards
参考:http://blog.itpub.net/18474/viewspace-1060728/
参考:metalink:How to switch the driving table in a hash join [ID 171940.1]
PLSQL_性能优化系列02_Oracle Join关联的更多相关文章
- PLSQL_性能优化系列14_Oracle High Water Level高水位分析
2014-10-04 Created By BaoXinjian 一.摘要 PLSQL_性能优化系列14_Oracle High Water Level高水位分析 高水位线好比水库中储水的水位线,用于 ...
- PLSQL_性能优化系列16_Oracle Tuning Analyze优化分析
2014-12-23 Created By BaoXinjian
- PLSQL_性能优化系列01_Oracle Index索引
2014-06-01 Created By BaoXinjian
- PLSQL_性能优化系列04_Oracle Optimizer优化器
2014-09-25 Created By BaoXinjian
- PLSQL_性能优化系列15_Oracle Explain Plan解析计划解读
2014-12-19 Created By BaoXinjian
- PLSQL_性能优化系列12_Oracle Index Anaylsis索引分析
2014-10-04 Created By BaoXinjian
- PLSQL_性能优化系列08_Oracle Insert / Direct Insert性能优化
2014-09-25 Created By BaoXinjian
- PLSQL_性能优化系列07_Oracle Parse Bind Variables解析绑定变量
2014-09-25 Created By BaoXinjian
- PLSQL_性能优化系列06_Oracle Soft Parse / Hard Parse软硬解析
2014-08-11 Createed By BaoXinjian
随机推荐
- JsonModelStrategy策略添加
今天在学习 zf2的时候,发现后端如果返回的是JsonModel的话,则在前台异步请求的时候发现取不到数据了,后来经过多次研究,才发现要在view_manager中创建策略,代ma是这样子的,stra ...
- SWIFT语言的概览
Swift用来写iOS和OS X程序.(估计也不会支持其它屌丝系统) Swift吸取了C和Objective-C的优点,且更加强大易用. Swift可以使用现有的Cocoa和Cocoa Touch框架 ...
- springMVC源码学习之:springMVC响应请求的几种方法
spring mvc 支持如下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void. ModelAndView @RequestMap ...
- linux内核启动流程[转]
启动流程一览 既然启动是很严肃的一件事,那我们就来了解一下整个启动的过程吧! 好让大家比较容易发现启动过程里面可能会发生问题的地方,以及出现问题后的解决之道! 不过,由於启动的过程中,那个启动管理程序 ...
- 如果将彩色图像和灰度图像一起放进 CNN 中去,会是什么结果?
如果将彩色图像和灰度图像一起放进 CNN 中去,会是什么结果? 今天,坑爹的实验,我处理 SUN397 的时候,忘记去掉灰度图了,结果,利用微调后的 model 提取 feature,悲剧的发现,无论 ...
- ARTICLES
https://blogs.msdn.microsoft.com/tess/2005/12/20/things-to-ignore-when-debugging-an-asp-net-hang/ ht ...
- Linux-SSL和SSH和OpenSSH,OpenSSL有什么区别
ssl是通讯链路的附加层.可以包含很多协议.https, ftps, ..... ssh只是加密的shell,最初是用来替代telnet的.通过port forward,也可以让其他协议通过ssh的隧 ...
- 如何用ABBYY把PDF转换成PPT
在电子科技迅速发展的今天,文件格式转换并不是什么稀罕事,因为现在都是电子化办公,出现很多文件格式,但是不同的场合需要的格式不同,所以常常需要进行文件格式的转换.PDF转换成PPT也是众多文件格式转换中 ...
- 怎么用ABBYY打开PDF文档
我们日常工作中接触的文档大多都是PDF格式的,这种格式的文件需要借助工具才能打开,大家最熟悉的无非就是Adobe了,但你知道吗?除了Adobe,OCR文字识别软件也可以打开PDF文档,比如ABBYY ...
- SQL Server 系统表简介
SQL Server 系统表简介 系统目录是由描述SQL Server 系统的数据库.基表.视图和索引等对象的结构的系统表组成.SQL Server 经常访问系统目录,检索系统正常运行所需的必要信息. ...