转-oracle pl/sql的批绑定和批量插入

                            

 

当Oracle运行PL/SQL时会使用两套引擎,所有procedural code由PL/SQL engine 完成,所有SQL由SQL engine处理。所以如果Oracle从一个collection中循环执行相同的DML操作,那么为了避免两套engine切换所消耗的系统资源,可以使用bulk binds来把所有的DML操作binding到一次操作中完成。这将极大提高PL/SQL的执行效率。
以下是简单的测试,用两种方式插入100000条数据,可以看到效率提高了7倍左右。

代码:

SQL
> CREATE TABLE test1(
  
2    id           NUMBER(10),
  
3    description  VARCHAR2(50));

Table created

SQL
> ALTER TABLE test1 ADD (
  
2    CONSTRAINT test1_pk PRIMARY KEY (id));

Table altered

SQL
> SET TIMING ON;

SQL> DECLARE
  
2    TYPE id_type          IS TABLE OF test1.id%TYPE;
  
3    TYPE description_type IS TABLE OF test1.description%TYPE;
  
4  
  5    t_id           id_type          
:= id_type();
  
6    t_description  description_type := description_type();
  
7  BEGIN
  8    
FOR i IN 1 .. 100000 LOOP
  9      t_id
.extend;
10      t_description.extend;
11  
12      t_id
(t_id.last)                   := i;
13      t_description(t_description.last) := 'Description: ' || To_Char(i);
14    END LOOP;
15  
16    
FOR i IN t_id.first .. t_id.last LOOP
17      INSERT INTO test1
(id, description)
18      VALUES (t_id(i), t_description(i));
19    END LOOP;
20  
21    COMMIT
;
22  END;
23  /

PL/SQL procedure successfully completed

Executed in 141.233 seconds

SQL
> truncate table test1;

Table truncated

Executed in 0.631 seconds

SQL
>
SQL> DECLARE
  
2    TYPE id_type          IS TABLE OF test1.id%TYPE;
  
3    TYPE description_type IS TABLE OF test1.description%TYPE;
  
4  
  5    t_id           id_type          
:= id_type();
  
6    t_description  description_type := description_type();
  
7  BEGIN
  8    
FOR i IN 1 .. 100000 LOOP
  9      t_id
.extend;
10      t_description.extend;
11  
12      t_id
(t_id.last)                   := i;
13      t_description(t_description.last) := 'Description: ' || To_Char(i);
14    END LOOP;
15  
16    FORALL i IN t_id
.first .. t_id.last
17      INSERT INTO test1
(id, description)
18      VALUES (t_id(i), t_description(i));
19  
20    COMMIT
;
21  END;
22  /

PL/SQL procedure successfully completed

Executed in 27.52 seconds

SQL
> select count(*) from test1;

  
COUNT(*)
----------
    
100000

Executed in 0.04 seconds

SQL
>
------------------------------------------------------------------
  
  

 

面我们使用上面那个例子中插入的100000条数据,来测试一下BULK COLLECT的威力。

代码:
    
    

SQL
> SET TIMING ON;
SQL>
SQL> DECLARE
  
2    TYPE id_type          IS TABLE OF test1.id%TYPE;
  
3    TYPE description_type IS TABLE OF test1.description%TYPE;
  
4  
  5    t_id           id_type          
:= id_type();
  
6    t_description  description_type := description_type();
  
7  
  8    CURSOR c_data IS
  9      SELECT
*
10      FROM   test1;
11  BEGIN
12    
FOR cur_rec IN c_data LOOP
13      t_id
.extend;
14      t_description.extend;
15  
16      t_id
(t_id.last)                   := cur_rec.id;
17      t_description(t_description.last) := cur_rec.description;
18    END LOOP;
19  END;
20  /

PL/SQL procedure successfully completed

Executed in 2.974 seconds

SQL
>
SQL> DECLARE
  
2    TYPE id_type          IS TABLE OF test1.id%TYPE;
  
3    TYPE description_type IS TABLE OF test1.description%TYPE;
  
4  
  5    t_id           id_type
;
  
6    t_description  description_type;
  
7  BEGIN
  8    SELECT id
, description
  9    BULK COLLECT INTO t_id
, t_description FROM test1;
10  END;
11  /

PL/SQL procedure successfully completed

Executed in 0.371 seconds

SQL
>



结论:当我们需要将大量的检索结果放入一个collection的时候,使用bulking将比直接使用cursor循环有效的多。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值