oracle性能提高---批量绑定

author:skate
time:2010-05-04

在我们的系统里,大家在写pl/sql时,处理多条记录时,几乎都是通过游标来完成的,这样是非常影响性能的。我们可以用批量绑定可以大大的改善。

 

批量绑定是oracle9i增加的特性,是指执行单次sql操作能传递所有集合元素的数据。通过绑定绑定变量可以极大的提高数据处理速度,提高应用程序的速度。批处理可以用与selectupdatedeleteinsert语句上进行批量数据的处理。

 

在我们写pl/sql的时候,oracle会为selectdml语句分配上下文区(这个步骤是非常耗资源的,oracle对于太频繁的切换,都换用其它方式代替,例如spin),游标就是上下文区的指针。所以在我们日常coding时,尽量少用cursor,虽然cursor使用很简单,但也带来很大的性能问题,我们现在系统里的游标就非常多。

批量绑定是使用bulk collectforall语句来完成的。

 

bulk collect:用与取得批量数据,只能用户,selectfetchdml返回字句

forall:适用于批量的dml

下面简单介绍下使用批量绑定和不使用批量绑定的性能对比的样例,一共两个例子:

测试表:

create table TESTA

(

  ID   NUMBER(6) primary key not null ,

  NAME VARCHAR2(10)

)

**********************************************************************************

例子1

Forall

使用批量绑定:

SQL> declare

  2   type id_table_type is table of number(6) index by binary_integer;

  3   type name_table_type is table of varchar2(10) index by binary_integer;

  4 

  5   id_table id_table_type;

  6   name_table name_table_type;

  7   start_time  number(10);

  8   end_time number(10);

  9 

 10  begin

 11 

 12  for i in 1..5000  loop

 13     id_table(i):=i;

 14     name_table(i):='name'||to_char(i);

 15  end loop;

 16 

 17  start_time:=dbms_utility.get_time;

 18  for i in 1..id_table.count loop

 19   insert into testa values(id_table(i),id_table(i))  ;

 20  end loop;

 21  end_time:=dbms_utility.get_time;

 22  dbms_output.put_line('总的执行时间(s)'|| (end_time-start_time)/100) ;

 23  end;

 24  /

 

总的执行时间(s).32

 

PL/SQL procedure successfully completed

 

Executed in 0.344 seconds

 

未使用批量绑定:

SQL> declare

  2   type id_table_type is table of number(6) index by binary_integer;

  3   type name_table_type is table of varchar2(10) index by binary_integer;

  4 

  5   id_table id_table_type;

  6   name_table name_table_type;

  7   start_time  number(10);

  8   end_time number(10);

  9 

 10  begin

 11 

 12  for i in 1..5000  loop

 13     id_table(i):=i;

 14     name_table(i):='name'||to_char(i);

 15  end loop;

 16 

 17  start_time:=dbms_utility.get_time;

 18  --for i in 1..id_table.count loop

 19  forall i in 1..id_table.count

 20   insert into testa values(id_table(i),id_table(i))  ;

 21  --end loop;

 22  end_time:=dbms_utility.get_time;

 23  dbms_output.put_line('总的执行时间(s)'|| (end_time-start_time)/100) ;

 24  end;

 25  /

 

总的执行时间(s).02

 

PL/SQL procedure successfully completed

 

Executed in 0.047 seconds

 

SQL>

对比:

批量绑定  Executed in 0.344 seconds

非批量绑定:Executed in 0.047 seconds

结果:性能提高近8

**************************************************************************************************************

例子2

bulk collect

未批量绑定(取100条记录):

SQL> declare

  2   type testa_table_type is table of testa%rowtype index by binary_integer;

  3   type id_table_type is table of number(6) index by binary_integer;

  4   type name_table_type is table of varchar2(10) index by binary_integer;

  5 

  6   cursor cur_testa is

  7   select *  from testa where rownum <=&num;

  8 

  9   id_table id_table_type;

 10   name_table name_table_type;

 11   testa_table testa_table_type;

 12 

 13   v_id number(6);

 14   v_name varchar2(10);

 15 

 16  begin

 17  for i in 1..5000  loop

 18     id_table(i):=i;

 19     name_table(i):='name'||to_char(i);

 20  end loop;

 21  forall i in 1..id_table.count

 22   insert into testa values(id_table(i),id_table(i))  ;

 23 

 24  -- select *  bulk collect into testa_table from testa where rownum <=&num;

 25  open cur_testa;

 26  loop

 27  fetch cur_testa into v_id,v_name;

 28  exit when cur_testa%notfound;

 29   --for i in 1..testa_table.count loop

 30      dbms_output.put_line('name is :'||v_name) ;

 31  end loop;

 32  close cur_testa;

 33  end;

 34  /

 

name is :2162

...

name is :2261

 

PL/SQL procedure successfully completed

 

Executed in 0.047 seconds

 

批量绑定(取100条记录):

 

SQL> declare

  2   type testa_table_type is table of testa%rowtype index by binary_integer;

  3   type id_table_type is table of number(6) index by binary_integer;

  4   type name_table_type is table of varchar2(10) index by binary_integer;

  5 

  6   id_table id_table_type;

  7   name_table name_table_type;

  8   testa_table testa_table_type;

  9 

 10  begin

 11  for i in 1..5000  loop

 12     id_table(i):=i;

 13     name_table(i):='name'||to_char(i);

 14  end loop;

 15  forall i in 1..id_table.count

 16   insert into testa values(id_table(i),id_table(i))  ;

 17 

 18   select *  bulk collect into testa_table from testa where rownum <=&num;

 19   for i in 1..testa_table.count loop

 20      dbms_output.put_line('name is :'||testa_table(i).name) ;

 21   end loop;

 22  end;

 23  /

 

name is :2162

..

name is :2261

 

PL/SQL procedure successfully completed

 

Executed in 0.031 seconds

 

对比:

批量绑定  Executed in 0.031 seconds

非批量绑定:Executed in 0.047 seconds

 

结果:性能提高近2

*****************************************************************************

我这里只是简单介绍下批量绑定,具体使用方法就需要大家自己练习了。

 

和批量绑定有关的知识如下:

 

一.oracle的数据类型分为几大类:标量(scalar),复合(composite),引用(reference)和lob

 

1.标量(scalar

合法的标量类型与数据库的列所使用的类型相同,也就是我常用的数据类型,

它又分为七个组:数字、字符、行、日期、行标识、布尔和可信。

 

2.复合(composite

标量类型是经过预定义的,利用这些类型可以衍生出一些复合类型(集合)。主要有记录、表。

 

3.引用(reference

它指向一个对象,例如游标就是引用

 

4.lob

LOB变量主要是用来存储大量数据的数据库字段

 

二.在处理复合类型的变量,oracle有对应的方法

 

oraclepl/sql里处理数据的方法

单行单列:用标量来存储

单行多列:用pl/sql记录来存储

多行单列:用pl/sql集合(索引表,嵌套表,varrary

多行多列:pl/sql记录表

 

 

 

 ------end-----

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值