测试说明:

MERGE是oracle提供的一种特殊的sql语法,非常适用于数据同步场景,即: (把A表数据插到B表,如果B表存在相同主键的记录则使用A表数据对B表进行更新) 数据同步的常规做法是先尝试插入,插入失败再进行更新,MERGE比这种常规做法效率高很多。 (特别是A与B表基本一致,同步时主键冲突比较多的情况,效率能相差10倍以上)

为了验证MERGE效率,我建了两张表,tab_test_C(初始化生成50000条记录)和tab_test_Q(初始化从tab_test_C生成40000条记录), 写了两个plsql脚本,分别将tab_test_C的数据同步到tab_test_Q,看它们效率区别。

第一个脚本使用merge语法,第二个脚本使用常规先插入,出现主键冲突的操作。

测试结果:
 使用merge语法的脚本同步数据耗时0.04秒,使用常规操作耗时14.77秒,效率差369倍

测试脚本:

SET SERVEROUTPUT ON
-- 启动计时 以便观察脚本执行时间
SET TIMING ON
SET TIME ON
-- 数据初始化
DROP TABLE tab_test_C;
CREATE TABLE tab_test_C
(
C1 VARCHAR2(512),
C2 VARCHAR2(512),
C3 VARCHAR2(512),
C4 VARCHAR2(512),
C5 VARCHAR2(512),
C6 VARCHAR2(512),
C7 VARCHAR2(512),
C8 VARCHAR2(512),
C9 VARCHAR2(512),
C10 VARCHAR2(512)
); DECLARE
v_total number;
BEGIN
v_total := 0;
LOOP
EXIT WHEN v_total >= 50000;
for cur in (select owner, object_name, subobject_name, object_id, data_object_id, object_type,
created, last_ddl_time, timestamp from all_objects where rownum < 101)
loop
insert into tab_test_C values (cur.owner, cur.object_name, cur.subobject_name,
cur.object_id, cur.data_object_id,
cur.object_type, cur.created,
cur.last_ddl_time, cur.timestamp, v_total);
v_total := v_total + 1;
end loop;
END LOOP;
COMMIT;
END;
/ -- 建唯一索引
select count(1) from tab_test_C;
create UNIQUE INDEX uid_test_c_1 on tab_test_C(C10);
--初始化tab_test_Q表数据,先从tab_test_C生成同步40000条数据,剩下10000条数据使用脚本同步过来
DROP TABLE tab_test_Q;
CREATE TABLE tab_test_Q AS SELECT * FROM tab_test_C where rownum < 40001;
create UNIQUE INDEX uid_test_q_1 on tab_test_Q(C10);
-- 验证数据未同步成功 此时记录数差1000
select count(*) from tab_test_Q;
-- 使用merge语法同步tab_test_C的数据到tab_test_Q
DECLARE
CURSOR cur is select * from tab_test_C;
type mergeArray_t is table of tab_test_C % ROWTYPE index by BINARY_INTEGER;
mergeArray mergeArray_t;
BEGIN
OPEN cur;
LOOP
EXIT WHEN cur % NOTFOUND;
FETCH cur bulk collect into mergeArray LIMIT 16; -- 每次限十几条记录,不要占用太多内存 这个数字调大点效率会更高
BEGIN
FORALL rw IN 1 .. mergeArray.count
MERGE INTO tab_test_Q A
USING (SELECT mergeArray(rw).C1 C1, mergeArray(rw).C2 C2, mergeArray(rw).C3 C3, mergeArray(rw).C4 C4,
mergeArray(rw).C5 C5, mergeArray(rw).C6 C6, mergeArray(rw).C7 C7, mergeArray(rw).C8 C8,
mergeArray(rw).C9 C9, mergeArray(rw).C10 C10 FROM DUAL) B
ON (A.C10 = B.C10)
WHEN MATCHED THEN
UPDATE SET A.C1 = mergeArray(rw).C1, A.C2 = mergeArray(rw).C2, A.C3 = mergeArray(rw).C3,
A.C4 = mergeArray(rw).C4, A.C5 = mergeArray(rw).C5,
A.C6 = mergeArray(rw).C6, A.C7 = mergeArray(rw).C7, A.C8 = mergeArray(rw).C8,
A.C9 = mergeArray(rw).C9
WHEN NOT MATCHED THEN
INSERT (C1, C2, C3, C4, C5, C6, C7, C8, C9, C10) VALUES(mergeArray(rw).C1, mergeArray(rw).C2,
mergeArray(rw).C3, mergeArray(rw).C4, mergeArray(rw).C5, mergeArray(rw).C6,
mergeArray(rw).C7, mergeArray(rw).C8, mergeArray(rw).C9, mergeArray(rw).C10);
-- DBMS_OUTPUT.PUT_LINE(mergeArray.count);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('error1');
END;
END LOOP;
CLOSE cur;
COMMIT;
END;
/
--耗时0.04秒
-- 验证数据同步成功
select count(*) from tab_test_Q;
--初始化tab_test_Q表数据,先从tab_test_C生成同步40000条数据,剩下10000条数据使用脚本同步过来
DROP TABLE tab_test_Q;
CREATE TABLE tab_test_Q AS SELECT * FROM tab_test_C where rownum < 40001;
create UNIQUE INDEX uid_test_q_1 on tab_test_Q(C10);
-- 验证数据未同步成功 此时记录数差1000
select count(*) from tab_test_Q;
-- 使用常规语法同步tab_test_C的数据到tab_test_Q
BEGIN
for cur in (select * from tab_test_C)
LOOP
BEGIN
INSERT INTO tab_test_Q(C1, C2, C3, C4, C5, C6, C7, C8, C9, C10)
VALUES(cur.C1, cur.C2, cur.C3, cur.C4, cur.C5, cur.C6, cur.C7, cur.C8, cur.C9, cur.C10);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN --唯一索引冲突时更新
UPDATE tab_test_Q SET C1 = cur.C1, C2 = cur.C2, C3 = cur.C3, C4 = cur.C4, C5 = cur.C5, C6 = cur.C6, C7 = cur.C7, C8 = cur.C8, C9 = cur.C9
WHERE C10 = cur.C10;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('error1');
END;
END LOOP;
COMMIT;
END;
/
--耗时14.77秒
-- 验证数据同步成功
select count(*) from tab_test_Q;

测试merge效率的更多相关文章

  1. merge效率

    测试merge效率   测试说明: MERGE是oracle提供的一种特殊的sql语法,非常适用于数据同步场景,即: (把A表数据插到B表,如果B表存在相同主键的记录则使用A表数据对B表进行更新) 数 ...

  2. Android测试提升效率批处理脚本(三)

    前言: 前面放出过几次批处理,这次只放一个环境检查的被管理员给打回来了,不得不再找找几个有含金量的放出来,请看正文~~~ 目录 1.Android环境检查 2.Android内存监控 3.模拟蓝牙手柄 ...

  3. Android测试提升效率批处理脚本(二)

    前言: 前面放出过一次批处理,本次再放出一些比较有用的批处理(获得当前包名.查看APP签名信息等),好长时没来写博客了,简单化,请看正文,更多脚本尽请期待~~~(不定期) 目录 1.[手机录屏(安卓4 ...

  4. Android测试提升效率批处理脚本

    前言: APP测试过程中,经常需要用的一些命令,如adb,每次敲命令,虽可以加深印象,但个人认为那即繁琐又浪费时间.本文贴出一些我使用的批处理,以及一点点小小技巧. 目录 1.[查看APK文件信息.b ...

  5. Python 编程实战提高测试工作效率实例之svn 文件管理

    #coding=utf-8 ''' Created on 2016年8月22日 @author:Tom Gao ''' importre importos importtime "" ...

  6. 测试数据库sql声明效率

    书写sql当被发现的声明.对于所期望的结果通常是更好地执行. 当面对这些实现的时候如何选择它的最好的,相对来说?这导致了这个博客的话题,如何测试sql效率 以下介绍几种sql语句測试效率的方法,大多数 ...

  7. Oracle Merge Into的用法详解

    1.    MERGE INTO 的用途         MERGE INTO 是Oracle 9i以后才出现的新的功能.那这个功能 是什么呢?         简单来说,就是:“有则更新,无则插入” ...

  8. Delphi容器类之---Tlist,TStringlist,THashedStringlist的效率比较

    转载自:http://www.ylzx8.cn/windows/delphi/73200.html 本人在做一个测试,服务器是IOCP的,我假定最大链接数是50000个. 测试背景:如果每个链接之间的 ...

  9. Android APP压力测试(二)之Monkey信息自动收集脚本

      Android APP压力测试(二) 之Monkey信息自动收集脚本 前言: 上一篇Monkey介绍基本搬抄官方介绍,主要是为了自己查阅方便.本文重点介绍我在进行Monkey时如何自动收集相关信息 ...

随机推荐

  1. 2.微信小程序-B站:需要先知道这些

    文件结构 小程序包含一个描述整体程序的 app 和多个描述各自页面的 page.一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下: 文件 必须 作用 app.js 是 小程序逻辑 app. ...

  2. 英语发音规则---oo

    英语发音规则---oo 一.总结 一句话总结: 1.重读音节词尾的字母组合oo发音素[u:]的音? too [tu:] adv.太;也 zoo [zu:] n.动物园 room [ru:m] n.房间 ...

  3. SpringMVC简单实例(看起来有用)

    SpringMVC简单实例(看起来有用) 参考: SpringMVC 基础教程 简单入门实例 - CSDN博客http://blog.csdn.net/swingpyzf/article/detail ...

  4. DBGrid1

    A.ShowMessage(IntToStr(Column.Index));   B.ShowMessage(IntToStr(dbgrid1.SelectedField.Index)); .得到当前 ...

  5. Python基础之字符串操作

    字符串的常用操作包括但不限于以下操作: 字符串的替换.删除.截取.复制.连接.比较.查找.分割等 这里将对字符串的内置操作方法进行总结归纳,重点是以示例的方式进行展示. 使用type获取创建对象的类 ...

  6. Unity3D之Mesh(七)绘制长方体

    前言: 从现在开始,终于感觉进入一点点正题了!动态创建三维立体模型mesh!依然从简单入手:长方体. 一.基本思路 由于是创建长方体mesh,由之前的研究得知,两个数据必须要有,即:顶点的数据:ver ...

  7. hibernate 框架搭建

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自 ...

  8. python基础-循环语句for\嵌套循环

    for循环格式: for index in range(0,3):#等同于range(3),取0\1\2 print(index) index = 0 starnames = ['xr1','xr2' ...

  9. 白话算法(6) 散列表(Hash Table)从理论到实用(上)

    处理实际问题的一般数学方法是,首先提炼出问题的本质元素,然后把它看作一个比现实无限宽广的可能性系统,这个系统中的实质关系可以通过一般化的推理来论证理解,并可归纳成一般公式,而这个一般公式适用于任何特殊 ...

  10. 洛谷 2312 / bzoj 3751 解方程——取模

    题目:https://www.luogu.org/problemnew/show/P2312 https://www.lydsy.com/JudgeOnline/problem.php?id=3751 ...