进行“批收集”及其时间选择的几中方法

这篇技巧性的文章介绍了进行“批收集”及其时间选择的几中方法。这些方法已经在Oracle 9.2.0.3.0上通过测试。下面是我要用到的表。它包含一些长字符串列。
create table bulktest (w number, x varchar2(100), y varchar2(100), z varchar2(100));

产生数据库表:
declare
  type typ_bulktest is table of bulktest%rowtype;
  arr_bulktest typ_bulktest := typ_bulktest();
begin
  arr_bulktest.extend(100000);
  for i in 1 .. 100000 loop
    arr_bulktest(i).w := i;
    arr_bulktest(i).x := rpad(i,100,'x');
    arr_bulktest(i).y := rpad(i,100,'y');
    arr_bulktest(i).z := rpad(i,100,'z');
  end loop;
  forall i in arr_bulktest.first .. arr_bulktest.last
    insert into bulktest
    values arr_bulktest(i);
end;
/

测试1:基于table%rowtype,在数组中放入隐含游标
declare
  type typ_bulktest is table of bulktest%rowtype;
  arr_bulktest typ_bulktest := typ_bulktest();
begin
  select *
  bulk collect into arr_bulktest
  from bulktest;
  dbms_output.put_line('bulk collected: ' || arr_bulktest.count);
end;
/
bulk collected: 100000
Elapsed: 00:00:01.13
Elapsed: 00:00:01.10
Elapsed: 00:00:01.08
Elapsed: 00:00:01.09
Elapsed: 00:00:01.09

测试2:往标量类型的并行数组中放入隐含游标
declare
  type typ_bulktest_w is table of bulktest.w%type;
  type typ_bulktest_x is table of bulktest.x%type;
  type typ_bulktest_y is table of bulktest.y%type;
  type typ_bulktest_z is table of bulktest.z%type;
  arr_bulktest_w typ_bulktest_w := typ_bulktest_w();
  arr_bulktest_x typ_bulktest_x := typ_bulktest_x();
  arr_bulktest_y typ_bulktest_y := typ_bulktest_y();
  arr_bulktest_z typ_bulktest_z := typ_bulktest_z();
begin
  select *
  bulk collect into
  arr_bulktest_w, arr_bulktest_x, arr_bulktest_y, arr_bulktest_z
  from bulktest;
  dbms_output.put_line('bulk collected: ' || arr_bulktest_w.count);
end;
/
bulk collected: 100000
Elapsed: 00:00:01.14
Elapsed: 00:00:01.12
Elapsed: 00:00:01.13
Elapsed: 00:00:01.13
Elapsed: 00:00:01.12

测试3:基于table%rowtype,往数组中放入“动态参考游标”。

declare
  v_ref sys_refcursor;
  type typ_bulktest is table of bulktest%rowtype;
  arr_bulktest typ_bulktest := typ_bulktest();
begin
  open v_ref for 'select * from bulktest';
  fetch v_ref bulk collect into arr_bulktest;
  dbms_output.put_line('bulk collected: ' || arr_bulktest.count);
end;
/
bulk collected: 100000
Elapsed: 00:00:01.12
Elapsed: 00:00:01.10
Elapsed: 00:00:01.10
Elapsed: 00:00:01.10
Elapsed: 00:00:01.10

测试4:往标量类型的并行数组中放入“动态参考游标”。
declare
  v_ref sys_refcursor;
  type typ_bulktest_w is table of bulktest.w%type;
  type typ_bulktest_x is table of bulktest.x%type;
  type typ_bulktest_y is table of bulktest.y%type;
  type typ_bulktest_z is table of bulktest.z%type;
  arr_bulktest_w typ_bulktest_w := typ_bulktest_w();
  arr_bulktest_x typ_bulktest_x := typ_bulktest_x();
  arr_bulktest_y typ_bulktest_y := typ_bulktest_y();
  arr_bulktest_z typ_bulktest_z := typ_bulktest_z();
begin
  open v_ref for 'select * from bulktest';
  fetch v_ref bulk collect into
  arr_bulktest_w, arr_bulktest_x, arr_bulktest_y, arr_bulktest_z;
  dbms_output.put_line('bulk collected: ' || arr_bulktest_w.count);
end;
/
bulk collected: 100000
Elapsed: 00:00:01.14
Elapsed: 00:00:01.12
Elapsed: 00:00:01.12
Elapsed: 00:00:01.12
Elapsed: 00:00:01.13

测试5:我的个人偏好:基于cursor%rowtype,往数组中放入明显的游标。
明显的游标给你查询上的弹性,并且,假如SELECT子句改变的话,你无需改写“批收集”。
declare
  cursor cur_bulktest is
  select * from bulktest;
  type typ_bulktest is table of cur_bulktest%rowtype;
  arr_bulktest typ_bulktest := typ_bulktest();
begin
  open cur_bulktest;
  fetch cur_bulktest
  bulk collect into arr_bulktest;
  dbms_output.put_line('bulk collected: ' || arr_bulktest.count);
end;
/
bulk collected: 100000
Elapsed: 00:00:01.41
Elapsed: 00:00:01.09
Elapsed: 00:00:01.10
Elapsed: 00:00:01.08
Elapsed: 00:00:01.09

分析:在Oracle 9.2中,不再需要使用并行标量游标。升级到Oracle 9.2.0.3.0是非常好的(我认为Oracle 9.2.0.4.0是最新的补丁修订版本),这样会给系统增加很多特色。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值