批量Insert导入数据实验

换了家新公司,在新的电脑上需要架设新的虚拟机,同时也需要重新导入数据。

在受了Robinson的影响下,开始多做实验,多记录,多思考。

1.老的脚本只是实现了业务需求,并没有考虑过执行效率问题:

DECLARE

I NUMBER; H NUMBER; R VARCHAR2(100); S VARCHAR2(100); T VARCHAR2(100);

U VARCHAR2(100); d varchar2(12); c varchar2(8); z number;

SEED NUMBER := 1; start_time date; end_time date;

BEGIN

DBMS_RANDOM.initialize(SEED);

z := 1;

c := 100005;

start_time :=sysdate;

FOR I IN 1 .. 60000 LOOP

select to_char(trunc(sysdate) - z, 'YYYYMMDD') into d from dual;

R := d || ABS(DBMS_RANDOM.random() / SEED);

S := d || ABS(DBMS_RANDOM.random() / SEED);

R := substr(R, 1, 14);

S := substr(S, 1, 14);

c := c + 1;

H := d || c;

if c = '100205' then

z := z + 1;

c := 100005;

end if;

INSERT INTO MONEY_IO_LIST t

(t.SERIAL_NO, t.voucherno, t.FLOWNO, t.CURRENTLYTIME, t.MEMBERID, t.ACCOUNTTYPE, t.BANKID,

t.MONEYTYPE, t.APPLYMONEY, t.SPONSOR, t.CURRENCYTYPE, t.REVERSEFLAG, t.IOFLAG,

t.STATECODE, t.applyoperid_e, t.applytime_e, t.approve1opid, t.approve1optime, t.approve2opid,

t.approve2optime, t.applyinputopid, t.applyinputoptime, t.exchangeid, t.exchangeaccount, t.JIZHANGOPID, t.JIZHANGOPTIME,

t.businesscompleteopid, t.businesscompleteoptime)

VALUES

(H, H, H, R, '000' || trunc(dbms_random.value(1, 10)), '1', '0' || trunc(dbms_random.value(1, 5)), '07',

FUN_NUM_CONVERSION(trunc(dbms_random.value(1, 100000)), 'N'), 'M', 'RMB', '0', 'I', dbms_random.string('U', 1),

'系统处理', S, '系统处理', S, '系统处理2', S, '系统处理', S, 'CFFEX', '31001559100059008883', '系统处理',

S, '中金所PSIS系统', 'S');

COMMIT;

END LOOP;

end_time :=sysdate;

dbms_output.put_line((end_time-start_time)*24*60*60);

END;

执行花费时间:75

2.将表设置成nologging模式后

执行花费时间:69

3.在优化了代码,分为每500笔提交一次,而不是每一笔提交一次。同时使用了/*+Append*/之后

if c = '100505' then

z := z + 1;

c := 100005;

COMMIT;

end if;

执行花费时间:42

4.最后我们对脚本进行大概,使用forall批量绑定:

DECLARE

I NUMBER; H NUMBER; R VARCHAR2(100); S VARCHAR2(100);

T VARCHAR2(100); U VARCHAR2(100); d varchar2(12);

c varchar2(8); z number; SEED NUMBER := 1; start_time date; end_time date;

TYPE type_serial IS TABLE OF money_io_list.serial_no%TYPE;

t_serial type_serial := type_serial();

TYPE type_current IS TABLE OF money_io_list.currentlytime%TYPE;

t_current type_current := type_current();

TYPE type_member IS TABLE OF money_io_list.memberid%TYPE;

t_member type_member := type_member();

TYPE type_time IS TABLE OF money_io_list.approve1optime%TYPE;

t_time type_time := type_time();

BEGIN

DBMS_RANDOM.initialize(SEED);

z := 1;

c := 100005;

start_time := sysdate;

FOR I IN 1 .. 60000 LOOP

select to_char(trunc(sysdate) - z, 'YYYYMMDD') into d from dual;

R := d || ABS(DBMS_RANDOM.random() / SEED);

S := d || ABS(DBMS_RANDOM.random() / SEED);

R := substr(R, 1, 14);

S := substr(S, 1, 14);

c := c + 1;

H := d || c;

if c = '100205' then

z := z + 1;

c := 100005;

end if;

t_serial.extend;

t_serial(i) := H;

t_current.extend;

t_current(i) := R;

t_member.extend;

t_member(i) := '000' || trunc(dbms_random.value(1, 10));

t_time.extend;

t_time(i) := S;

END LOOP;

forall i in t_serial.first .. t_serial.last

INSERT INTO MONEY_IO_LIST t

(t.SERIAL_NO, t.voucherno, t.FLOWNO, t.CURRENTLYTIME, t.MEMBERID, t.ACCOUNTTYPE, t.BANKID,

t.MONEYTYPE, t.APPLYMONEY, t.SPONSOR, t.CURRENCYTYPE, t.REVERSEFLAG, t.IOFLAG, t.STATECODE,

t.applyoperid_e, t.applytime_e, t.approve1opid, t.approve1optime, t.approve2opid, t.approve2optime, t.applyinputopid,

t.applyinputoptime, t.exchangeid, t.exchangeaccount, t.JIZHANGOPID, t.JIZHANGOPTIME, t.businesscompleteopid, t.businesscompleteoptime)

VALUES

(t_serial(i), t_serial(i), t_serial(i), t_current(i), t_member(i), '1', '0' || trunc(dbms_random.value(1, 5)), '07',

FUN_NUM_CONVERSION(trunc(dbms_random.value(1, 100000)), 'N'), 'M', 'RMB', '0', 'I', dbms_random.string('U', 1),

'系统处理', t_time(i), '系统处理', t_time(i), '系统处理2', t_time(i), '系统处理', t_time(i), 'CFFEX', '31001559100059008883',

'系统处理', t_time(i), '中金所PSIS系统', t_time(i));

Commit;

end_time := sysdate;

dbms_output.put_line((end_time - start_time) * 24 * 60 * 60);

END;

执行花费时间:25

Summary:

75秒降低到25秒,只花了原来1/3的时间。看来批量绑定虽然写法比较繁琐但是效率还是很强大的。可能在更大的数据量上nologging会发挥更强大的效率。限于条件限制,这次没有使用parallel来插入数据。

:Forall时遇到的小问题 Ora-06531Reference to uninitialized collection

今天调试存储过程出现“ORA-06531: 引用未初始化的收集错误,仔细查找了一下metalink,发现是需要初始化,而以前采用的表结构的都没有作过初始化这个步骤,后来看了一下,是因为声明的方式没有按照表的方式声明,而是自己手工写的字段。先寒一个! metalink上面看到,这种类型应该像下面那样使用:

–Create EMPLOYEE_TYPE
CREATE OR REPLACE type employee_type as object(
empid number,
empname varchar2(20),
job varchar2(20));
/
–Create EMPLOYEE_TAB_TYPE
CREATE OR REPLACE type employee_tab_type as table of employee_type ;
/
–Create DEPARTMENT_TYPE — using employee_tab_type
CREATE OR REPLACE type department_type as object(
deptid number,
deptname varchar2(20),
deptlocation varchar2(20),
emp_tab employee_tab_type);
/
DECLARE

/* Initialize the collection , else you will get ORA-06531: Reference to uninitialized collection */

my_emp employee_tab_type:=employee_tab_type();
my_dept department_type;
Begin
my_emp.extend; —
必须指定,否则会报指针越界
my_emp(1):=employee_type(2,’Savitha’,'mgr’); —
如果是record也可以直接赋值employee_type
my_dept :=department_type(1,’RESEARCH’,'India’,my_emp);
END;

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12180666/viewspace-1040368/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12180666/viewspace-1040368/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值