PLSQL_性能优化系列17_Oracle Merge Into和Update更新效率
2015-05-21 Created By BaoXinjian
一、摘要
以前只考虑 merge into 只是在特定场合下方便才使用的,今天才发现,merge into 竟然会比 update 在更新数据时有这么大的改进。
其实呢,merge into部分的update和update也没啥不同的,不同的地方在于使用merge into后执行计划变了。
merge方法是最简洁,效率最高的方式,在大数据量更新时优先使用这种方式。
1. 基本语法
merge into test1 using test2 on (test1.id = test2.id) when matched then update set test1.name = nvl2(test1.name,test2.name,test1.name);
update内联视图方式:使用这种方式必须在test2.id上有主键 (这里很好理解,必须保证每一个test1.id对应在test2里只有一条记录,如果test2中有多条对应的记录,怎么更新test1)
或者on (test1.id = test2.id, test1.name = test2.name ....),通过多栏位对比,确认唯一记录,类似Unique Index
2. 使用并行,加快大量数据更新:
merge /*+parallel(test1,4)*/ into test1 using test2 on (test1.id = test2.id) when matched then update set test1.name = nvl2(test1.name,test2.name,test1.name);
二、测试案例 - Update / Merge Into
1. 创建测试数据
create table test1 as select * from dba_objects where rownum<=10000;--10000条记录create table test2 as select * from dba_objects--73056条记录
2. 直接Update时间和效率
SQL> alter system flush shared_pool;System altered.SQL> alter system flush buffer_cache;System altered.SQL> set linesize 400 pagesize 400 SQL> set autot trace SQL> set timing on SQL> update test1 t12 set t1.object_name = (select t2.object_name3 from test2 t24 where t2.object_id = t1.object_id);10000 rows updated.Elapsed: 00:06:33.35Execution Plan ----------------------------------------------------------0 UPDATE STATEMENT Optimizer=ALL_ROWS (Cost=2923252 Card=10011 Bytes=790869)1 0 UPDATE OF 'TEST1'2 1 TABLE ACCESS (FULL) OF 'TEST1' (TABLE) (Cost=40 Card=10011 Bytes=790869)3 1 TABLE ACCESS (FULL) OF 'TEST2' (TABLE) (Cost=292 Card=772 Bytes=60988)Statistics ----------------------------------------------------------430 recursive calls11122 db block gets15275257 consistent gets1175 physical reads4058752 redo size520 bytes sent via SQL*Net to client668 bytes received via SQL*Net from client3 SQL*Net roundtrips to/from client7 sorts (memory)0 sorts (disk)10000 rows processed
3. 通过Merge Into时间和效率
SQL> alter system flush shared_pool;System altered.Elapsed: 00:00:00.45 SQL> alter system flush buffer_cache;System altered.Elapsed: 00:00:00.71 SQL> merge into test1 t12 using test2 t23 on (t1.object_id = t2.object_id)4 when matched then5 update set t1.object_name = t2.object_name;10000 rows merged.Elapsed: 00:00:00.92Execution Plan ----------------------------------------------------------0 MERGE STATEMENT Optimizer=ALL_ROWS (Cost=1243 Card=10011 Bytes=1321452)1 0 MERGE OF 'TEST1'2 1 VIEW3 2 HASH JOIN (Cost=1243 Card=10011 Bytes=4264686)4 3 TABLE ACCESS (FULL) OF 'TEST1' (TABLE) (Cost=40 Card=10011 Bytes=2192409)5 3 TABLE ACCESS (FULL) OF 'TEST2' (TABLE) (Cost=292 Card=77163 Bytes=15972741)Statistics ----------------------------------------------------------1224 recursive calls10279 db block gets1586 consistent gets1191 physical reads2803872 redo size526 bytes sent via SQL*Net to client634 bytes received via SQL*Net from client3 SQL*Net roundtrips to/from client12 sorts (memory)0 sorts (disk)10000 rows processed
三、解析计划
1. 通过Update的解析计划
SQL> set autot off SQL> update /*+gather_plan_statistics*/ test1 t12 set t1.object_name = (select t2.object_name3 from test2 t24 where t2.object_id = t1.object_id);10000 rows updated.Elapsed: 00:04:32.81 SQL> select * from table(dbms_xplan.display_cursor(null,null,'iostats'));PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------- SQL_ID c8qt9a54qgmqg, child number 0 ------------------------------------- update /*+gather_plan_statistics*/ test1 t1 set t1.object_name = (select t2.object_name from test2 t2where t2.object_id = t1.object_id)Plan hash value: 3883393169-------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | -------------------------------------------------------------------------------------- | 0 | UPDATE STATEMENT | | 1 | | 0 |00:04:32.73 | 10M| | 1 | UPDATE | TEST1 | 1 | | 0 |00:04:32.73 | 10M| | 2 | TABLE ACCESS FULL| TEST1 | 1 | 10011 | 10000 |00:00:00.17 | 133 | |* 3 | TABLE ACCESS FULL| TEST2 | 10000 | 772 | 10000 |00:04:31.51 | 10M| -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): ---------------------------------------------------3 - filter("T2"."OBJECT_ID"=:B1)Note ------ dynamic sampling used for this statement (level=2)26 rows selected.Elapsed: 00:00:01.38
2. 通过Merge Into的解析计划
SQL> merge /*+gather_plan_statistics*/2 into test1 t13 using test2 t24 on (t1.object_id = t2.object_id)5 when matched then6 update set t1.object_name = t2.object_name;10000 rows merged.Elapsed: 00:00:00.52 SQL> select * from table(dbms_xplan.display_cursor(null,null,'iostats'));PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------- SQL_ID 9n4tc6tvwaj9c, child number 0 ------------------------------------- merge /*+gather_plan_statistics*/ into test1 t1 using test2 t2 on (t1.object_id = t2.object_id) when matched then update set t1.object_name = t2.object_namePlan hash value: 818823782---------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ---------------------------------------------------------------------------------------- | 0 | MERGE STATEMENT | | 1 | | 0 |00:00:00.47 | 11458 | | 1 | MERGE | TEST1 | 1 | | 0 |00:00:00.47 | 11458 | | 2 | VIEW | | 1 | | 10000 |00:00:00.33 | 1179 | |* 3 | HASH JOIN | | 1 | 10011 | 10000 |00:00:00.25 | 1179 | | 4 | TABLE ACCESS FULL| TEST1 | 1 | 10011 | 10000 |00:00:00.08 | 133 | | 5 | TABLE ACCESS FULL| TEST2 | 1 | 77163 | 73056 |00:00:00.26 | 1046 | ---------------------------------------------------------------------------------------- Predicate Information (identified by operation id): ---------------------------------------------------3 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")Note ------ dynamic sampling used for this statement (level=2)28 rows selected.Elapsed: 00:00:00.15
四、结果分析
1. 测试结果对比:update和merge into 都更新1w条记录,
update耗时6分钟,逻辑读消耗15275257;
merge into 耗时6秒钟,消耗逻辑读1586,相差太大了。
2. 其实看着执行计划,这个结果也很容易理解:
update采用的类似nested loop的方式,对更新的每一行,都会对查询的表扫描一次;
merge into这里选择的是hash join,则针对每张表都是做了一次 full table scan,对每张表都只是扫描一次。
3. Oracle官方建议,在大数据更新过程中,也是通过使用Merge Into代替Update
Thanks and Regards
参考: http://blog.csdn.net/xiexbb/article/details/4242063
PLSQL_性能优化系列17_Oracle Merge Into和Update更新效率相关推荐
- PLSQL_性能优化系列15_Oracle Explain Plan解析计划解读
2014-12-19 Created By BaoXinjian 一.摘要 在SQL语句的执行计划中,包含很多字段项和很多模块,其不同字段代表了不同的含义且在不同的情形下某些字段.模块显示或不显示,下 ...
- PLSQL_性能优化系列04_Oracle Optimizer优化器
2014-09-25 Created By BaoXinjian 一.摘要 1. Oracle优化器介绍 本文讲述了Oracle优化器的概念.工作原理和使用方法,兼顾了Oracle8i.9i以及最新的 ...
- PLSQL_性能优化系列07_Oracle Parse Bind Variables解析绑定变量
2014-09-25 Created By BaoXinjian 一.绑定变量用法和使用场合 使用绑定变量的重要性:如果不使用绑定变量而使用常量,会导致大量硬解析.由于硬解析的种种危害,不使用绑定变量 ...
- PLSQL_性能优化系列20_Oracle Result Cash结果缓存
20150528 Created By BaoXinjian 一.摘要 SQL 查询结果高速缓存可在数据库内存中对查询结果集和查询碎片启用显式高速缓存. 存储在共享池(Share Pool)中的专用内 ...
- PLSQL_性能优化系列10_Oracle Array数据组优化
2014-09-25 Created By BaoXinjian 一.摘要 集合是Oracle开发中经常遇到的情况,Oracle集合分为三种情况:索引表集合(index by table).嵌套表集合 ...
- 推荐:Java性能优化系列集锦
Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难.随着10多年Java平台的改进以及新出现的多核多处理器,Java软件的性能和扩展性已经今非昔比了.现代JVM持续演 ...
- 【Linux 性能优化系列】Linux 性能优化 -- CPU 性能篇(三) Linux 软中断
[Linux 性能优化系列]Linux 性能优化 -- CPU 性能篇(三) Linux 软中断 [1]相关概念 [1.1]中断 中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力:为了减少 ...
- 性能优化系列:每个程序员都应该知道的数字
目录 前言 正文 看这些数据的目的 1)CPU非常非常快 2)内存很快了,但是相比CPU来说还是太慢了 3)磁盘性能非常非常慢 4)磁盘顺序I/O比随机读I/O快很多 5)网络传输也是比较耗时的,基本 ...
- Android性能优化系列之apk瘦身
Android性能优化系列之布局优化 Android性能优化系列之内存优化 为什么APK要瘦身.APK越大,在下载安装过程中,他们耗费的流量会越多,安装等待时间也会越长:对于产品本身,意味着下载转化率 ...
最新文章
- 电子白板 矢量 编码_当涉及白板编码采访时,请记住准备
- 【鸿蒙 HarmonyOS】UI 布局 ( 网格布局 TableLayout )
- Android TextView里直接显示图片的三种方法
- java.lang.NoClassDefFoundError: javax/xml/bind/ValidationException
- 为CentOS 6 配置本地YUM源
- 面试常考题---交换变量
- python小波分解与重构_小波分解和重构
- mongodb 分组聚合_mongodb 聚合命令
- OpenCv图像像素操作
- 医院耗材管理系统开发_17
- python爬虫爬取中国天气网_初识python 之 爬虫:爬取中国天气网数据
- 【ceph】ceph osd启动及peering过程中osdmap相关加载和更新流程
- 【MySQL】MySQL的四种事务隔离级别
- 内网穿透工具(永久免费、永不限速、开源)、一键启动、页面操作(支持window,mac),自定义二级域名
- c语言三个灯一直亮 一个灯闪烁,电脑键盘不能用了,三个指示灯一直在闪,也用不了,是为什么...
- 复旦大学,计算机考研情况
- hdu2907 凸包+简单搜索
- 机器学习模型中的损失函数loss function
- maven 修改maven本地仓库的位置
- 顽石互动创始人吴刚:走高品质的发展道路