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 ...
随机推荐
- sql上传木马
第十周笔记—SQLmap和sql注入上传木马 目录 第十周笔记—SQLmap和sql注入上传木马 SQL注入 上传木马 SQLmap 六大模块 命令 参数 三种请求方式 取得系统shell sqlma ...
- Web访问原理-从输入URL到页面加载完成的过程中都发生了什么事情?
从输入URL到页面加载完成的过程中都发生了什么事情?--这是一个经典的面试题: 主要是关于计算机网络方面的知识基础,对于非科班计算机自学web开发的同学可能理解起来就很困难. StackOverFlo ...
- 【Android】drawable VS mipmap
Android Studio 创建工程后默认的资源文件夹如下图所示: 一直有些疑惑的是 mipmap 和 drawable 文件夹有什么区别,以及是否还需要创建 drawable-xhdpi, dra ...
- Restful API 中的错误处理
简介 随着移动开发和前端开发的崛起,越来越多的 Web 后端应用都倾向于实现 Restful API. Restful API 是一个简单易用的前后端分离方案,它只需要对客户端请求进行处理,然后返回结 ...
- eclipse的下载安装配置
1.在eclipse官网下载与你电脑版本相对应的安装包.链接:https://www.eclipse.org/downloads/eclipse-packages/ 2.下载与eclipse版本相对应 ...
- Zabbix编译安装(全)
一.前言 (一).概述 Zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案,Zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系 ...
- .net开源生态,WTM与NCC
天下大势,分久必合,合久必分.改朝换代都如花开花谢,过眼云烟,更别提开发语言的更迭了. 我们所坚持的,只是那最初的感动,那“只是在人群中多看了你一眼”的惊艳.三十年河东,三十年河西,不忘初心,方得始终 ...
- python_0基础开始_day05
第五节 一.字典 python的数据结构之一 字典 —— dict 定义:dic = {"key":"dajjlad"} 作用:存储数据,大量,将数据和数据起到 ...
- SpringBoot 集成Jedis操作set
题外话: Redis是个有趣的东西,相信搞java的或多或少都会用到,面试时也总离不开问Redis,之前觉得redis只是用做缓存,飞快!也因为最初在封装底层的时候,使用Redisson,所以大部分都 ...
- hadoop学习(四)----windows环境下安装hadoop
因为我们不能在线上环境进行调试hadoop,这样就只能在本地先调试好了再放到线上去啦.我本地是windows环境,今天先记下windows下搭建hadoop2.7的步骤. 1 本地环境 windows ...