oracle 优化之批量处理bulk correct 和 forall
世风之狡诈多端,到底忠厚人颠扑不破; 末俗以繁华相尚,终觉冷淡处趣味弥长。
BULK COLLECT运用
在游标中运用
declare
cursor C_CUR is SELECT * FROM T_TEST;
TYPE T_TYPE IS TABLE OF T_TEST%ROWTYPE;----需要定义一个数据记录的类型
C_REC T_TYPE;
begin
open C_CUR ;
loop
FETCH C_CUR BULK COLLECT INTO C_REC LIMIT 5000;
EXIT WHEN C_REC.COUNT=0; ---这个地方不可以用 exit when C_CUR%notfound 会导致少记录 如果用的话可以在循环结束的时候用,这是区别于普通游标的一个关键地方
for I in C_REC.first..C_REC.LAST
LOOP
INSERT INTO MXQ(ID,NAME) VALUES (C_REC(I).ID,C_REC(I).NAME);
UPDATE MXQ SET ID=C_REC(I).ID WHERE NAME=C_REC(I).NAME;
END LOOP;
EXIT WHEN C_CUR%NOTFOUND;--粉色标明的地方 可以任意选择一个退出循环
end loop;
close C_CUR;
end;
forall 运用
forall也是一个集合提取 它不同于for循环的地方在于
1.它不是一个循环 不用接loop 和 end loop
2.forall 后面只能跟一个dml语句.否则会报错.
综合运用BULK CORRECT 和 forall之后以上sql核心部分可以改写成这样
loop
FETCH C_CUR BULK COLLECT INTO C_REC LIMIT 5000;
EXIT WHEN C_REC.COUNT=0;
forall I in C_REC.first..C_REC.LAST
INSERT INTO MXQ(ID,NAME) VALUES (C_REC(I).ID,C_REC(I).NAME);----forall 后面只能跟一个dml语句
forall I in C_REC.first..C_REC.LAST
UPDATE MXQ SET ID=C_REC(I).ID WHERE NAME=C_REC(I).NAME;
end loop;
关于fetch bulk collect into 游标记录类型的声明
声明一个表中的记录
DECLARE
CURSOR C_CUR IS SELECT * FROM TAB_TEST;
TYPE C_TYPE IS TABLE OF TAB_TEST%ROWTYPE;
C_REC C_TYPE;
声明多个表中的记录
DECLARE
CURSOR C_CUR IS SELECT A.ROWID,B.NAME FROM TAB_TEST_1 A,TAB_TEST_2 B WHERE A.ID=B.ID;
TYPE C_TYPE_REC IS RECORD (ROWID VARCHAR2(32),
NAME TAB_TEST_2%TYPE );----因为是两个表中的字段所以需要声明一个记录类型record包含这两个表的字段
TYPE C_TYPE IS TABLE OF C_TYPE_REC;----把类型声明成刚才那个记录的类型, 注意不需要%ROWTYPE 因为C_TYPE_REC已经是一个记录类型了
C_REC C_TYPE;
测试 效率 数据270万 环境11g
用BULK COLLECT 和 forall
写法一
DECLARE
CURSOR C_CUR IS SELECT A.ROWID FROM mxq A;
TYPE C_TYPE IS TABLE OF C_CUR%ROWTYPE;
C_REC C_TYPE;
BEGIN
OPEN C_CUR;
LOOP
FETCH C_CUR BULK COLLECT INTO C_REC LIMIT 10000;
EXIT WHEN C_REC.count=0;
FORALL I IN C_REC.FIRST..C_REC.LAST
UPDATE mxq A SET A.BEIZHU=(SELECT BEIZHU FROM mxq_1 B WHERE A.SNAME=B.SNAME ) WHERE A.ROWID=C_REC(I).ROWID;
commit;
END LOOP;
CLOSE C_CUR;
END; 222秒
写法二
DECLARE
CURSOR C_CUR IS SELECT A.ROWID,B.BEIZHU FROM mxq A,mxq_1 B WHERE A.SNAME=B.SNAME;
TYPE C_TYPE IS TABLE OF C_CUR%ROWTYPE;
C_REC C_TYPE;
BEGIN
OPEN C_CUR;
LOOP
FETCH C_CUR BULK COLLECT INTO C_REC LIMIT 10000;
EXIT WHEN C_REC.count=0;
FORALL I IN C_REC.FIRST..C_REC.LAST
UPDATE mxq A SET A.BEIZHU=C_REC(I).BEIZHU WHERE A.ROWID=C_REC(I).ROWID;
commit;
END LOOP;
CLOSE C_CUR;
END; 267秒
这两个写法加载进游标的数据记录不一样经过测试发现 差距不大.
用两种写法分别使用批处理和不使用批处理
不用BULK COLLECT 和 forall
写法一
DECLARE
CURSOR C_CUR IS SELECT A.ROWID FROM mxq A;
C_REC C_CUR%ROWTYPE;
BEGIN
OPEN C_CUR;
LOOP
FETCH C_CUR INTO C_REC ;
EXIT WHEN C_CUR%NOTFOUND;
UPDATE mxq A SET A.BEIZHU=(SELECT BEIZHU FROM mxq_1 B WHERE A.SNAME=B.SNAME ) WHERE A.ROWID=C_REC.ROWID;
commit;
END LOOP;
CLOSE C_CUR;
END;1000秒
写法二
DECLARE
CURSOR C_CUR IS SELECT A.ROWID,B.BEIZHU FROM mxq A,mxq_1 B WHERE A.SNAME=B.SNAME;
C_REC C_CUR%ROWTYPE;
BEGIN
OPEN C_CUR;
LOOP
FETCH C_CUR INTO C_REC ;
EXIT WHEN C_CUR%NOTFOUND;
UPDATE mxq A SET A.BEIZHU=C_REC.BEIZHU WHERE A.ROWID=C_REC.ROWID;
commit;
END LOOP;
CLOSE C_CUR;
END;804秒
不用批处理的dml语句 写法二比写法一快的明显一些快了200秒.
总结
1.批处理比单条处理快了大概4倍.
2.sql写法也一定程度上决定了dml的速度.
3可以用并发来提高dml速度,可以看我之前对并发做的测试.
最后送看文章的小伙伴一句话
乾坤未定,你我皆是黑马.
转载于:https://www.cnblogs.com/throughRiversandLake/p/10894482.html
oracle 优化之批量处理bulk correct 和 forall相关推荐
- Oracle优化07-分析及动态采样-DBMS_STATS 包
思维导图 07系列文章 Oracle优化07-分析及动态采样-直方图 Oracle优化07-分析及动态采样-DBMS_STATS 包 Oracle优化07-分析及动态采样-动态采样 DBMS_STAT ...
- Oracle 优化和性能调整
Oracle 优化和性能调整 分析评价Oracle数据库性能主要有数据库吞吐量.数据库用户响应时间两项指标.数据库用户响应时间又可以分为系统服务时间和用户等待时间两项,即: 数据库用户响应时间=系统 ...
- Oracle优化器:星型转换
Oracle 8i中引入了星型转换(star transformation)的优化器新特性以便更有效地处理星型查询.星型查询语句多用于基于星型模型设计的数据仓库应用中.星型模型的称谓源于该种模型以图形 ...
- Oracle优化之表连接方式
Oracle优化之表连接方式 在Oracle数据库中,两个表之间的表连接方法有排序合并连接.嵌套循环连接.哈希连接和笛卡尔连接四种 1.排序合并连接(sort merge join) 排序合并连接是一 ...
- Oracle 优化器_表连接
概述 在写SQL的时候,有时候涉及到的不仅只有一个表,这个时候,就需要表连接了.Oracle优化器处理SQL语句时,根据SQL语句,确定表的连接顺序(谁是驱动表,谁是被驱动表及 哪个表先和哪个表做链接 ...
- Oracle 优化器
什么是优化器 优化器是Oracle中的一个核心模块,它的作用是为用户输入的SQL选择一个它计算出来的最高效的执行计划.SQL语句在Oracle中的执行过程如下图所示: 基于规则优化器RBO 基于规则的 ...
- Oracle优化07-分析及动态采样-动态采样
思维导图 07系列文章 Oracle优化07-分析及动态采样-直方图 Oracle优化07-分析及动态采样-DBMS_STATS 包 Oracle优化07-分析及动态采样-动态采样 动态采样Dynam ...
- Oracle优化07-分析及动态采样-直方图
思维导图 07系列文章 Oracle优化07-分析及动态采样-直方图 Oracle优化07-分析及动态采样-DBMS_STATS 包 Oracle优化07-分析及动态采样-动态采样 概述 获取准确的段 ...
- SDE+ORACLE优化配置
原文 SDE+ORACLE优化配置 SDE的性能取决于: 首先操作系统的性能:其次是Oracle的性能,再次是SDE的性能. 第一:操作系统,无非是内存.CPU.带宽等. 可以有待提高的地方:第一.硬 ...
最新文章
- 联想m7400pro更换墨粉盒怎么清零_打印耗材到底怎么选
- 花指令——多个指令共用字节
- leetcode 822. Card Flipping Game | 822. 翻转卡片游戏(Java)
- 数论--中国剩余定理模板
- 使用sqlyog创建数据库
- StreamDM:基于Spark Streaming、支持在线学习的流式分析算法引擎
- 力扣226. 翻转二叉树(JavaScript)
- 装修好的房子多久能住 入住需要注意什么?
- Oracle修改实例名SID
- RedHat Linux 9.0 操作系统测试题2
- 如何使用Excel绘制图表?
- ffmpeg 音频合并
- 果壳格言——偶像的力量近在眼前
- 近日onedrive突然消失问题的解决
- 第三天,【1124】接口,注册,登录
- 盘点2009年商场百货创意促销手段 秒杀当道
- win10连Android机,win10系统Android手机或iPhone连接的操作方法
- word中输入 千分之一 万分之一 符号
- win7系统调用tts的语音朗读功能
- Android9--android 10.0 去掉未知来源弹窗 默认授予安装未知来源权限
热门文章
- python bottle web框架上传静态文件与加载静态文件
- 易语言---时间操作
- 【模板引擎】Springboot整合ThymeleafThymeleaf基本语法
- 分组[测试点分支+二分图判定]
- xshell添加脚本
- amazeui页面分析5
- matlab导出jar包错误Error: An error occurred while shelling out to javac(erro code = 1)解决办法...
- 安全与隐私没有允许任何来源选项
- Eclipse 启动问题:'Initilizing Java Tooling' has encountered a problem(。。。)
- 【转】CreateWindowEx异常原因汇总