【问题背景】 2013-08-02 为某地市做了1个脚本用于帮客户账户添加一个新的账本。犯了一个很二的错,存储过程如下(SQL记录用户以后查询),一晚上只执行了190W数据 脚本如下 数据库中总共有500W或者更多的客户。
【问题原因】 但由于每次循环时都COMMIT提交,导致效率低,
相比之下,每1W条提交,肯定是更有效率的
因为每一次commit会触发LGWR做很多相应的操作,将重做BUFFER中的数据写到日志当中,然后去处理回滚段的相应信息,让回滚段中900秒(默认)之外的信息可以被重写。
也就是每一次commit都会带来大量的操作。
但是,commit的数据,也并不是全部完成之后提交一次效率就高了,因为还要看data_buffer的大小。
commit与数据写DBF的时机是没啥关系的,那个取决于CKPT.
【解决方法】 分批次处理 : 例如处理完10000个客户后才提交一次,使用MOD除法函数实现
【效率低的问题脚本】
--20130802
--liuyong
--修正信息: 1-普通预存款余额
create or replace procedure prc_createacctbook is
cursor cur_account is
select *
from accounten a
where a.isdefaultid = 1
and a.businessid = 2
and not exists (select *
from acctbooken ac
where a.accountid_pk = ac.objid
and ac.balancetypeid_pk = 1);
V_ACCOUNTID NUMBER(8);
V_ACCOUNTCODE VARCHAR2(50);
V_ACCOUNTNAME VARCHAR2(70);
V_CUSTOMERID NUMBER(8);
V_MEN varchar2(50);
V_OBJTYPEID NUMBER(2);
V_BALANCETYPEID NUMBER(5);
V_BALANCETYPENAME VARCHAR2(50);
V_account_book_name VARCHAR2(70);
begin
V_MEN := 'p20130802LY'; --补丁记录备注
V_OBJTYPEID := '1'; --对象类型为账户
V_BALANCETYPEID := '1';
V_BALANCETYPENAME := '普通预存款余额';
--ADD ACCTBOOK
for vv_account in cur_account loop
V_ACCOUNTID := vv_account.accountid_pk;
V_ACCOUNTCODE := vv_account.accountcodestr;
V_ACCOUNTNAME := vv_account.accountnamestr;
V_CUSTOMERID := vv_account.customerid_pk;
--设置余额账本名称
if (length(concat(V_ACCOUNTNAME, V_BALANCETYPENAME)) > 25) then
V_account_book_name := V_ACCOUNTNAME;
else
V_account_book_name := concat(V_ACCOUNTNAME, V_BALANCETYPENAME);
end if;
--添加账本
insert into acctbooken
(ACCTBOOKID_PK,
BALANCETYPEID_PK,
ACCTBOOKNAMESTR,
ACCTBOOKCODESTR,
STARTDT,
BALANCEID,
CYCLE_UPPERID,
CYCLE_LOWERID,
STATUSID,
CREATEDT,
MEM,
CUSTOMERID,
OBJTYPEID,
OBJID)
values
(seq_acctbooken.nextval, --ID
1,
V_account_book_name, --accountname+typename
CONCAT(V_ACCOUNTCODE, V_BALANCETYPEID), --accountcode+typecode
to_date('19700101', 'yyyymmdd'),
'0',
'0',
'0',
1,
sysdate,
V_MEN,
V_CUSTOMERID,
V_OBJTYPEID,
V_ACCOUNTID);
--添加余额对象关系
insert into ACCTBALANCEOBJEN
(ACCBALANCEOBJID_PK,
ACCTBOOKID_PK,
OBJTYPEID,
OBJID,
MEM,
CREATEDT,
STATUSID)
values
(SEQ_ACCTBALANCEOBJEN.NEXTVAL,
seq_acctbooken.currval,
V_OBJTYPEID,
V_ACCOUNTID,
V_MEN,
sysdate,
1);
update payprojecten po
set po.statusid = 0, po.mem = V_MEN || po.mem
where po.accountid_pk = V_ACCOUNTID;
insert into PAYPROJECTEN
(PAYPROJECTID_PK,
PAYMETHODID_PK,
ACCOUNTID_PK,
ACCTBOOKID_PK,
PAYTYPEID,
PRIID,
STATUSID,
CREATEDT,
MEM)
values
(SEQ_PAYPROJECTEN.Nextval,
'111', --paymathod.cash
V_ACCOUNTID,
seq_acctbooken.currval,
1,
0,
1,
sysdate,
V_MEN);
COMMIT;
end loop;
end;
/
【修改后脚本如下】
--20130802
create or replace procedure prc_createacctbook is
cursor cur_account is
select *
from accounten a
where a.isdefaultid = 1
and a.businessid = 2
and not exists (select *
from acctbooken ac
where a.accountid_pk = ac.objid
and ac.balancetypeid_pk = 1);
V_ACCOUNTID NUMBER(8);
V_ACCOUNTCODE VARCHAR2(50);
V_ACCOUNTNAME VARCHAR2(70);
V_CUSTOMERID NUMBER(8);
V_MEN varchar2(50);
V_OBJTYPEID NUMBER(2);
V_BALANCETYPEID NUMBER(5);
V_BALANCETYPENAME VARCHAR2(50);
V_account_book_name VARCHAR2(70);
V_NUM NUMBER;
begin
V_MEN := 'p20130802LY'; --补丁记录备注
V_OBJTYPEID := '1';
V_BALANCETYPEID := '1';
V_BALANCETYPENAME := '普通预存款余额';
V_NUM := 0; --
--ADD ACCTBOOK
for vv_account in cur_account loop
V_ACCOUNTID := vv_account.accountid_pk;
V_ACCOUNTCODE := vv_account.accountcodestr;
V_ACCOUNTNAME := vv_account.accountnamestr;
V_CUSTOMERID := vv_account.customerid_pk;
if (length(concat(V_ACCOUNTNAME, V_BALANCETYPENAME)) > 25) then
V_account_book_name := V_ACCOUNTNAME;
else
V_account_book_name := concat(V_ACCOUNTNAME, V_BALANCETYPENAME);
end if;
insert into acctbooken
(ACCTBOOKID_PK,
BALANCETYPEID_PK,
ACCTBOOKNAMESTR,
ACCTBOOKCODESTR,
STARTDT,
BALANCEID,
CYCLE_UPPERID,
CYCLE_LOWERID,
STATUSID,
CREATEDT,
MEM,
CUSTOMERID,
OBJTYPEID,
OBJID)
values
(seq_acctbooken.nextval, --ID
1,
V_account_book_name, --accountname+typename
CONCAT(V_ACCOUNTCODE, V_BALANCETYPEID), --accountcode+typecode
to_date('19700101', 'yyyymmdd'),
'0',
'0',
'0',
1,
sysdate,
V_MEN,
V_CUSTOMERID,
V_OBJTYPEID,
V_ACCOUNTID);
insert into ACCTBALANCEOBJEN
(ACCBALANCEOBJID_PK,
ACCTBOOKID_PK,
OBJTYPEID,
OBJID,
MEM,
CREATEDT,
STATUSID)
values
(SEQ_ACCTBALANCEOBJEN.NEXTVAL,
seq_acctbooken.currval,
V_OBJTYPEID,
V_ACCOUNTID,
V_MEN,
sysdate,
1);
update payprojecten po
set po.statusid = 0, po.mem = V_MEN || po.mem
where po.accountid_pk = V_ACCOUNTID;
insert into PAYPROJECTEN
(PAYPROJECTID_PK,
PAYMETHODID_PK,
ACCOUNTID_PK,
ACCTBOOKID_PK,
PAYTYPEID,
PRIID,
STATUSID,
CREATEDT,
MEM)
values
(SEQ_PAYPROJECTEN.Nextval,
'111', --paymathod.cash
V_ACCOUNTID,
seq_acctbooken.currval,
1,
0,
1,
sysdate,
V_MEN);
-- COMMIT; 注销提交,修改为10000提交一次
V_NUM := V_NUM + 1;
IF MOD(V_NUM, 10000) = 0 THEN
COMMIT; --除10000 为0时提交
END IF;
end loop;
end;
/
- Oracle Update 语句语法与性能分析 - 多表关联
Oracle Update 语句语法与性能分析 - 多表关联 为了方便起见,建立了以下简单模型,和构造了部分测试数据: 在某个业务受理子系统BSS中, SQL 代码 --客户资料表 create ...
- Oracle中HWM与数据库性能的探讨
Oracle中HWM与数据库性能的探讨 一.什么是高水位 HWM(high water mark),高水标记,这个概念在segment的存储内容中是比较重要的.简单来说,HWM就是一个segment中 ...
- Oracle AWRDD报告生成和性能分析
我写的SQL调优专栏:https://blog.csdn.net/u014427391/article/category/8679315 对于局部的,比如某个页面列表sql,我们可以使用Oracle的 ...
- oracle 事务 与 提交
Oracle事务 一般事务(DML)即数据修改(增.删.改)的事务事务会将所有在事务中被修改的数据行加上锁(行级锁),来阻止其它人(会话)同时对这些数据的修改操作.当事务被提交或回滚后,这些数据才会被 ...
- Oracle 性能优化的基本方法
Oracle 性能优化的基本方法概述 1)设立合理的性能优化目标. 2)测量并记录当前性能. 3)确定当前Oracle性能瓶颈(Oracle等待什么.哪些SQL语句是该等待事件的成分). 4)把等待事 ...
- DBA_Oracle性能优化的基本方法概述(方法论)
2014-12-18 Created By BaoXinjian
- 性能调优之提高 ASP.NET Web 应用性能的 24 种方法和技巧
性能调优之提高 ASP.NET Web 应用性能的 24 种方法和技巧 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对 ...
- ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍
如果我是C罗 原文 ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍 sequence在ORACLE中应用十分广泛,就是序列号的意思,会自动增加指定变数,如逐次增加1或者2或者 ...
- oracle中如何对字符串进行去除空格的方法
oracle中如何对字符串进行去除空格的方法 今天学习了一下oracle中如何对字符串进行去除空格的方法,这里总结一下.了解到的方法主要有两种:Trim函数以及Replace函数.下面我详细的介绍一下 ...
随机推荐
- 《AngularJS》5个实例详解Directive(指令)机制
本文整理并扩展了<AngularJS>这本书第六章里面的内容,此书近期即将由电子工业出版社出版,敬请期待口令:Angular 1.一点小说明 指令的作用:实现语义化标签 我们常用的HTML ...
- Ubuntu 上安装 MongoDB
官方安装文档:https://docs.mongodb.com/manual/installation/ 安装环境: mongodb-linux-x86_64-ubuntu1404-3.2.6.tgz ...
- ARM寻址方式,王明学learn
ARM寻址方式 所谓寻址方式就是处理器根据指令中给出的信息来找到指令所需操作数的方式. 一.立即数寻址 立即数寻址,是一种特殊的寻址方式,操作数本身就在指令中给出,只要取出指令也就取到了操作数.这个操 ...
- [转]svn常用命令
谢谢原作者:http://blog.sina.com.cn/s/blog_963453200101eiuq.html 1.检出svn co http://路径(目录或文件的全路径) [本地目录全路 ...
- WPF标准控件模板查看程序(文件里面)
xaml <Window x:Class="ControlTemplateBrowser.MainWindow" xmlns="http://schemas.mic ...
- 【转】Struts2国际化
原文章:http://www.cnblogs.com/hellokitty1/p/5083663.html 简单理解 国际化简称i18n,其来源是英文单词 internationalizati ...
- phpstudy配置ssl
https://yunpan.cn/cPEyzVycbkiE3 (提取码:03aa) 1.重写规则:http://www.cnphp.info/htaccess-rewrite.html 2.相关文档 ...
- MySQL的多表查询(笛卡尔积原理)
先确定数据要用到哪些表. 将多个表先通过笛卡尔积变成一个表. 然后去除不符合逻辑的数据(根据两个表的关系去掉). 最后当做是一个虚拟表一样来加上条件即可. 注意:列名最好使用表别名来区别. 笛卡尔积 ...
- Android学习系列(43)--使用事件总线框架EventBus和Otto
事件总线框架 针对事件提供统一订阅,发布以达到组件间通信的解决方案. 原理 观察者模式. EventBus和Otto 先看EventBus的官方定义: Android optimized event ...
- hdu1150 匈牙利
http://acm.split.hdu.edu.cn/showproblem.php?pid=1150 题目大意:有两台机器A和B以及N个需要运行的任务.每台机器有M种不同的模式,而每个任务都恰好在 ...