Oracle大量数据更新策略
生产上要修改某个产品的产品代号, 而我们系统是以产品为中心的, 牵一发而动全身, 涉及表几乎覆盖全部, 有些表数据量是相当大的, 达到千万, 亿级别.
单纯的维护产品代号的 SQL 是不难的, 但是性能是最大的问题, 最后采用了 rowid+forall分批更新策略.
细节涉及:
游标(rowid)
dbms_sql.Urowid_Table
(异常声明;)
fetch v_rowid_cursor bulk collect into v_rowid_table limit v_once_commit; ...
forall i in 1 .. v_rowid_table.count save exceptions ...
完整代码:
PL/SQL存储过程分批更新↓
--rowid+forall批量更新
declare
v_total_count integer default 500000; --待更新目标记录总计
v_once_commit integer default 10000; --单次提交量
v_pre_prod_code char(8) := '';
v_new_prod_code char(8) := '9031000X';
v_dml_name varchar2(100) := 'update tb_cust_vol_list 20181215 01';
v_suc_count integer := 0; --成功提交计数
v_err_count integer := 0; --失败记录数
v_curr_batch integer := 0; --当前提交批次
v_start_time date := sysdate; --开始时间
--待更新目标记录rowids
cursor v_rowid_cursor is
select rowid from tb_cust_vol_list
where prod_code = v_pre_prod_code
order by rowid; --rowid排序,提高效率
v_rowid_table dbms_sql.Uv_rowid_table; --临时单次rowid放置表
v_error exception; --异常声明
pragma exception_init(v_error, -24381); --指定ora-错误码 begin
--操作日志
insert into tb_dml_log values (
v_dml_name,
v_total_count,
v_once_commit,
v_start_time,
v_start_time,
0, 0, 0, 0, 0
);
commit; open v_rowid_cursor; --打开rowids游标
loop
exit when v_rowid_cursor%notfound;
--临时rowids表
fetch v_rowid_cursor bulk collect into v_rowid_table limit v_once_commit;
exit when v_rowid_table.count = 0; begin
forall i in 1 .. v_rowid_table.count save exceptions
--rowid定位行更新
update tb_cust_vol_list set prod_code=v_new_prod_code where rowid=v_rowid_table(i);
exception
when v_error then --目标异常
dbms_output.put_line('ora-24381, error in array DML !');
dbms_output.put_line('exception count: ' || sql%bulk_exceptions.count);
v_err_count := v_err_count + sql%bulk_exceptions.count;
when others then
dbms_output.put_line('ora-XXX error occurred !');
dbms_output.put_line('exception count: ' || sql%bulk_exceptions.count);
v_err_count := v_err_count + sql%bulk_exceptions.count;
end; v_suc_count := v_suc_count + v_rowid_table.count;
v_curr_batch := v_curr_batch + 1;
--更新log
update tb_dml_log a set
a.curr_time=sysdate,
a.curr_cost=ceil((sysdate-v_start_time)*24*60*60),
a.curr_batch=v_curr_batch,
a.process=v_suc_count/a.total_count,
a.suc_count=v_suc_count,
a.err_count=v_err_count
where a.dml_name=v_dml_name;
commit; end loop; dbms_output.put_line('total error count: ' || v_err_count);
end;
有帮助的博客:
https://blog.csdn.net/leinuo180/article/details/23344647
其他考虑:
如果有的表目标数据实在太大, 就算上述优化依然很费时间, 可将此表的目标数据拆分, 比如按月, 按编号.. 分几个脚本, 维护时并行执行.
查询语句获取所有目标数据的 rowid 时, 如果占比很大(索引空间大), 可以尝试禁用索引查询, 使用全表并行查(网上看到的,本人还未尝试).
超大表要注意索引空间的维护.
@20190126更新
批量数据更新方式
1)表重建
即先新建复制表(create 新表(...) as select ... from 旧表 where ...),然后删除旧表(drop),最后修改表名(rename 新表名 to 旧表名),最后恢复表结构(约束,索引等)。
2)rowid+forall PL/SQL存储过程更新
即上面的办法
3)JDBC程序分批更新
优点是DB无关性,性能也不慢,只是数据量太大(千万级)时,力不从心。
Oracle大量数据更新策略的更多相关文章
- ASP.NET Cache 实现依赖Oracle的缓存策略
ASP.NET 中的缓存提供了对SQL依赖项的支持,也就是说当SQL SERVER数据库中的表或行中的数据被更改后,缓存中的页面就失效,否则,页面输出可一直保留在缓存当中.这确实为程序员提供了方便.但 ...
- Oracle RMAN备份策略
建立增量备份:如果数据库运行于不归档模式下,只能在数据库干净关闭的情况下 ( 以 normal .immediate . transactional 方式关闭 ) 才能进行一致性的增量备份,如果数据库 ...
- Oracle数据库备份策略:全备与增量备份
一.RMAN全备份 在数据量比较小.或者数据库服务器性能很强大的情况下,可以每天进行一次全备份. 全被策略如下 1.crontab定时任务,避开业务繁忙时段 ##################### ...
- Web系统与自控系统数据通讯架构 之 OPC DA DataChangeEventHandler 非热点数据更新策略 ,
在使用OPC 采集 工控数据时,在DA模式下.采集数据通常用到 DataChangeEventHandler这个事件.但有时会遇到一些问题,就是当数据不变化时时不会触发 DataChange 这个事件 ...
- Oracle的Recyclebin策略
1.从oracle10g开始删除数据库表的时候并不是真正删除,而是放到了recyclebin中,这个过程类似 windows里面删除的文件会被临时放到回收站中. 2.删除的表系统会自动给他重命名就是你 ...
- Oracle备份及备份策略
第二章. 了解备份的重要性 可以说,从计算机系统出世的那天起,就有了备份这个概念,计算机以其强大的速度处理能力,取代了很多人为的工作,但是,往往很多时候,它又是那么弱不禁风,主板上的芯片.主板电路.内 ...
- oracle与DB2
1.体系结构,DB2的实例和数据库分开的做法,我个人还是比较喜欢的,因为实例可以创建多个,数据库的恢复直接恢复到实例下就可以了,相对ORACLE简单多了. 2.管理工具,DB2的管理工具做得太简陋了, ...
- DB2和Oracle区别
转 http://blog.chinaunix.net/uid-7374279-id-2057574.html 写在前面:今天客户来访(日本人),问我DB2和Oracle区别.因为不是DBA(勉强的理 ...
- 微軟将从 .NET 4 以后的版本弃用 System.Data.OracleClient 以及Oracle 的各种连接方法
这是微软官方 ADO.NET Team Blog 去年就公布的消息: http://blogs.msdn.com/adonet/archive/2009/06/15/system-data-oracl ...
随机推荐
- 从flink-example分析flink组件(3)WordCount 流式实战及源码分析
前面介绍了批量处理的WorkCount是如何执行的 <从flink-example分析flink组件(1)WordCount batch实战及源码分析> <从flink-exampl ...
- javascript基础学习第三天
☞ 命名法: 小驼峰命名法 和 大驼峰命名法(帕斯卡命名法) 变量命名规则:遵循小驼峰命名法 [变量名第一个字母小写后面每一个单词的首字母大写] var userNameAge; 函数命名规则:遵循帕 ...
- Python3发送邮件功能
Python3实现邮件发送功能 import smtplib from email.mime.text import MIMEText # 导入模块 class SendEmail: def send ...
- Bean Validation完结篇:你必须关注的边边角角(约束级联、自定义约束、自定义校验器、国际化失败消息...)
每篇一句 没有任何技术方案会是一种银弹,任何东西都是有利弊的 相关阅读 [小家Java]深入了解数据校验:Java Bean Validation 2.0(JSR303.JSR349.JSR380)H ...
- UE4 打包详细流程
这两天试着把之前做的一个UE4项目在安卓机上运行下,于是乎有了下面的一个打包血泪史. 首先呢,肯定是下载好了UE的源码了,我用的是4.18. 安装步骤可以先参考下官方的教程http://api.unr ...
- Vue组件间通信-Vuex
上回说到Vue组件间通讯,最后留了一个彩蛋~~~Vuex.Vuex是另一种组件通讯的方法,这节来说说Vuex(store仓库). 首先Vuex需要安装,安装的方式有很多,在这里就不一一细说了.我是通过 ...
- JDK、JRE、JVM之间的区别和联系
JDK : Java Development ToolKit(Java开发工具包).JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工 ...
- kubernetes集群升级的正确姿势
kubernetes社区非常活跃,每季度都会发布一个release.但是线上集群业务可用性要求较高,场景复杂,任何微小的变更都需要非常小心,此时跟随社区版本进行升级略显吃力.但是为了能够使用到最新的一 ...
- elk系列教程:docker中安装配置elk
elasticSearch Docker安装elasticsearch: docker pull docker.io/elasticsearch:7.2.0 启动: docker run -p 920 ...
- exe4j打包--exe转安装包
前面一篇已经详细的说明了打包成exe的步骤了,下面谈谈exe如何压缩成安装文件.这里用到之前的另外一个软件,具体软件看这篇文章 exe4j打包成exe 打开inno 编辑器 打开软件后我们选择 用[脚 ...