【问题背景】 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】多次提交造成性能慢及处理方法的更多相关文章

  1. Oracle Update 语句语法与性能分析 - 多表关联

    Oracle Update 语句语法与性能分析 - 多表关联   为了方便起见,建立了以下简单模型,和构造了部分测试数据: 在某个业务受理子系统BSS中, SQL 代码 --客户资料表 create ...

  2. Oracle中HWM与数据库性能的探讨

    Oracle中HWM与数据库性能的探讨 一.什么是高水位 HWM(high water mark),高水标记,这个概念在segment的存储内容中是比较重要的.简单来说,HWM就是一个segment中 ...

  3. Oracle AWRDD报告生成和性能分析

    我写的SQL调优专栏:https://blog.csdn.net/u014427391/article/category/8679315 对于局部的,比如某个页面列表sql,我们可以使用Oracle的 ...

  4. oracle 事务 与 提交

    Oracle事务 一般事务(DML)即数据修改(增.删.改)的事务事务会将所有在事务中被修改的数据行加上锁(行级锁),来阻止其它人(会话)同时对这些数据的修改操作.当事务被提交或回滚后,这些数据才会被 ...

  5. Oracle 性能优化的基本方法

    Oracle 性能优化的基本方法概述 1)设立合理的性能优化目标. 2)测量并记录当前性能. 3)确定当前Oracle性能瓶颈(Oracle等待什么.哪些SQL语句是该等待事件的成分). 4)把等待事 ...

  6. DBA_Oracle性能优化的基本方法概述(方法论)

    2014-12-18 Created By BaoXinjian

  7. 性能调优之提高 ASP.NET Web 应用性能的 24 种方法和技巧

    性能调优之提高 ASP.NET Web 应用性能的 24 种方法和技巧   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对 ...

  8. ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍

    如果我是C罗 原文 ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍 sequence在ORACLE中应用十分广泛,就是序列号的意思,会自动增加指定变数,如逐次增加1或者2或者 ...

  9. oracle中如何对字符串进行去除空格的方法

    oracle中如何对字符串进行去除空格的方法 今天学习了一下oracle中如何对字符串进行去除空格的方法,这里总结一下.了解到的方法主要有两种:Trim函数以及Replace函数.下面我详细的介绍一下 ...

随机推荐

  1. Delphi中线程类TThread实现多线程编程1---构造、析构……

    参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832053.html Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大 ...

  2. MySql中delimiter的作用是什么?

    这个命令与存储过程没什么关系吧.其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了.默认情况下,delimiter是分号;.在命令行客户端中,如果有一行命令以分号结束,那么 ...

  3. 攻城狮在路上(叁)Linux(二十八)--- 打包命令:tar

    首先介绍一下tar打包命令的基本格式,下面的三种之间不能混淆. tar [-j|-z] [cv] [-f 新文件名] file1 file2 ...; tar [-j|-z] [tv] [-f 新文件 ...

  4. android 入门-android Studio 解决方案

    一.当提示 解决方案: 1. 2. 二.从这步到这步 的时候,可能遇见下面的问题. 解决方案: 更新一下build-tools 19.1.0版本 放到你的sdk里并重启as. 三. 当遇见这样的情况 ...

  5. 关于RTP负载类型及时间戳介绍

    转自:http://www.360doc.com/content/11/1018/13/1016783_157133781.shtml 首 先,看RTP协议包头的格式: 前12个字节在每一个RTP p ...

  6. Effective C++ 之 0 导读(Introduction)

    Effective C++ 导读 (Introduction) 术语(terminology) 声明式 (declaration) 是告诉编译器某个东西的名称和类型(type),但略去细节.以下都是声 ...

  7. loj 1037(状压dp)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25914 思路:dp[state]表示当前状态下要消耗的最小的sho ...

  8. Mac OS 您需要安装旧 Java SE 6 运行环境才能打开“XXX” 问题

    问题描述: 今天在Mac OS上安装一个app的时候提示 “您需要安装旧 Java SE 6 运行环境才能打开 XXX” ,在网上搜索了一下,有说要改app的info.plist文件的,将其中的JVM ...

  9. SQL SERVER数据库的表中修改字段的数据类型后,不能保存

      在数据库里面建了一个表,可是由于对SQL SERVER的建表功能不熟悉,不知道把主键设成什么是好,就先设置了个TEXT类型,可是后来朋友们告诉我说,TEXT类型容易让数据文件变得很大,还 是改成一 ...

  10. 移动端-解决ios连续点击页面上移问题

    引入js即可 //解决ios双击页面上移问题//在项目中测试不紧input/button这些表单控件有这个问题,p,div等也有问题,于是乎就直接在body开刀了(function(){ var ag ...