ITPub博客

首页 > 数据库 > Oracle > PL/SQL 批量Bind Forall 的性能表现

PL/SQL 批量Bind Forall 的性能表现

原创 Oracle 作者:Karsus 时间:2009-03-13 10:37:15 0 删除 编辑

周三 AP 人员准备对一个千万级的Table A进行Update, 要求A表中,每一行的Column MO的值要和B表中的MO值想等,对应的逻辑是A.SN=B.SN, SN是Unique。

[@more@]

本来他们想一个SQL搞定(怎么可能…),后来觉得不可以,之后又来找我们商量要怎么做,因为毕竟是一个7X24的系统,CPU Loading比较重

最后确定的方案是用PL/SQL分批Update,同时用批量绑定的方式。

下面是当时作的测试对比。

测试平台是一套空载的10gR2 RAC,存储是ISCSI。

测试表COA_SN_D,是一个百万级的Table,作为A表;便于测试,提出其COA_SN和MO构造出测试表UPD_COA (B),然后Update (B)的MO,得到新MO值。

本次测试选择更新26W 行数据。

以下是测试Procedure:

首先是传统Cursor做法:

declare

UPD TP.UPD_COA%rowtype;

CURSOR C1 is select COA_SN,MO from TP.UPD_COA;

T1 number(20);

T2 number(20);

begin

T1:=dbms_utility.get_cpu_time;

open c1;

fetch c1 into UPD;

WHILE c1%found Loop

update TP.COA_SN_D set TP.COA_SN_D.MO=UPD.MO

where TP.COA_SN_D.COA_SN=UPD.COA_SN;

fetch c1 into UPD;

end loop;

close c1;

T2:=dbms_utility.get_cpu_time;

DBMS_OUTPUT.put_line('Execution Time is '||to_char(T2-T1));

end;

时间是1499

批量Bind FORALL:

declare

type sn is table of TP.UPD_COA.COA_SN%TYPE;

sn1 sn;

T1 number(20);

T2 number(20);

begin

T1:=dbms_utility.get_cpu_time;

select COA_SN bulk collect into sn1 from TP.UPD_COA;

forall j in sn1.first..sn1.last

update TP.COA_SN_D set TP.COA_SN_D.MO=(select TP.UPD_COA.MO from TP.UPD_COA where TP.UPD_COA.COA_SN=sn1(j))

where TP.COA_SN_D.COA_SN=sn1(j);

T2:=dbms_utility.get_cpu_time;

DBMS_OUTPUT.put_line('CPU Time is '||to_char(T2-T1));

exception

when others then

DBMS_OUTPUT.put_line('UPDATE FAILED. Index='||SQL%BULK_EXCEPTIONS(1).ERROR_INDEX);

DBMS_OUTPUT.put_line(SQLERRM(-SQL%BULK_EXCEPTIONS(1).ERROR_CODE));

commit;

end;

时间是758.

减少了一半的CPU使用时间。在执行时间上也差了有一半。批量Bind在减少了PL/SQL引擎和SQL引擎之间的切换后,带来的收益非常可观。

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

请登录后发表评论 登录
全部评论
  • 博文量
    43
  • 访问量
    150218