merge效率
测试merge效率
测试说明:
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效率的更多相关文章
- 测试merge效率
测试说明: MERGE是oracle提供的一种特殊的sql语法,非常适用于数据同步场景,即: (把A表数据插到B表,如果B表存在相同主键的记录则使用A表数据对B表进行更新) 数据同步的常规做法是先尝试 ...
- mysql学习笔记--数据库视图
一.视图 1. 概念 a. 视图是一张虚拟表,它表示一张表的部分或多张表的综合的结构 b. 视图仅仅是表结构,没有数据.视图的结构和数据建立在表的基础上 2. 创建视图 a. 语法: create [ ...
- PLSQL_性能优化系列17_Oracle Merge Into和Update更新效率
2015-05-21 Created By BaoXinjian 一.摘要 以前只考虑 merge into 只是在特定场合下方便才使用的,今天才发现,merge into 竟然会比 update 在 ...
- Merge into语句用法及其效率问题
Merge into语句用法及其效率问题 /*Merge into 详细介绍MERGE语句用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行查询, ...
- merge into 和 update 的效率对比
以前只考虑 merge into 只是在特定场合下方便才使用的,今天才发现,merge into 竟然会比 update 在更新数据时有这么大的改进.其实呢,merge into部分的update和u ...
- SQL Tuning 基础概述06 - 表的关联方式:Nested Loops Join,Merge Sort Join & Hash Join
nested loops join(嵌套循环) 驱动表返回几条结果集,被驱动表访问多少次,有驱动顺序,无须排序,无任何限制. 驱动表限制条件有索引,被驱动表连接条件有索引. hints:use_n ...
- [LeetCode] Merge k Sorted Lists 合并k个有序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 这 ...
- No.023:Merge k Sorted Lists
问题: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexit ...
- No.021:Merge Two Sorted Lists
问题: Merge two sorted linked lists and return it as a new list. The new list should be made by splici ...
随机推荐
- Vmware虚拟机 centos7设置固定IP地址
参考文章:https://www.cnblogs.com/lfhappy/p/10798400.html https://blog.csdn.net/u014466635/article/d ...
- 题解 BZOJ1026 & luogu P2657 [SCOI2009]windy数 数位DP
BZOJ & luogu 看到某大佬AC,本蒟蒻也决定学习一下玄学的数位$dp$ (以上是今年3月写的话(叫我鸽神$qwq$)) 思路:数位$DP$ 提交:2次 题解:(见代码) #inclu ...
- 分布式hadoop 架构图
zk:zookeeper NN:namenode DN:datanode ZF Failover Controller:简称zkfc ,是zk的客户端,只运行在主备的namenode上,主要作用是判断 ...
- .net上传大文件的解决方案
ASP.NET上传文件用FileUpLoad就可以,但是对文件夹的操作却不能用FileUpLoad来实现. 下面这个示例便是使用ASP.NET来实现上传文件夹并对文件夹进行压缩以及解压. ASP.NE ...
- 蓝桥历年试题 DNA对比
[编程题](满分27分) 脱氧核糖核酸即常说的DNA,是一类带有遗传信息的生物大分子.它由4种主要的脱氧核苷酸(dAMP.dGMP.dCMT和dTMP)通过磷酸二酯键连接而成.这4种核苷酸可以分别记为 ...
- codeforces1209E2 状压dp,枚举子集
题意 给一个n行m列的矩阵,每一列可以循环移位,问经过任意次移位后每一行的最大值总和最大为多少. 分析 每一行的最大值之和最大,可以理解为每一行任意选择一个数使它们的和最大. 设\(dp[i][S]\ ...
- [Vue] : Vue指令
Vue指令之 v-cloak v-cloak是解决解决插值表达式的闪烁问题 . 给插值表达式的元素加上v-cloak <p v-cloak>{{ msg }}</p> 为v-c ...
- 写简单的tb(testbench)文件来测试之前的FSM控制的LED
先上我之前写的状态机控制的led代码led_test.v module led_test(clk,led_out); input clk; :] led_out; initial begin led_ ...
- vmware中桥接模式和NAT的区别
桥接模式 在桥接模式下,VMWare虚拟出来的操作系统就像是局域网中的一台独立的主机(主机和虚拟机处于对等地 位),它可以访问网内任何一台机器.在桥接模式下,我们往往需要为虚拟主机配置IP地址.子网掩 ...
- 用单元测试来调试SilverFish AI
[TestFixture] public class AiTest { [Test] public void Test() { Settings.Instance.LogFolderPath = @& ...