Oracle——Bulk

前端之家收集整理的这篇文章主要介绍了Oracle——Bulk前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

需求:向一张表插入1百万的数据,用存储过程实现。

测试:用第一种实现用了30S,如果改为bulk实现,不到2s。

sql> drop table t purge;

表已删除

sql> set timing on
sql> create table t (x  int);
sql> begin
      for i in 1.. 1000000
       loop
           execute immediate 'insert into t values(:x)' using i;
       end loop;
       commit;
      end;
    /


PL/sql 过程已成功完成。

已用时间: 00: 00: 30.24

sql> truncate table t;

表被截断。

sql> DECLARE
      TYPE V_X IS table of t%rowtype;
      records V_X;
      cursor cur_query is select rownum x from dual connect by level <=1000000;
    begin
      open cur_query;
      loop
        fetch cur_query bulk collect into records  LIMIT 100000;
          FORALL i in 1 .. records.count
           INSERT INTO T values records(i);
          exit when cur_query%notfound;
      end loop;
      commit;
   end;
   /


已用时间: 00: 00: 01.48

优化原理:

1.Oracle使用2个引擎来执行sql代码块:sql引擎和PL/sql引擎,sql语句会导致在两个引擎之间进行context switch,从而影响性能

2.从本质上讲,使用特殊的block或者subprogram来降低context switches可以提高性能sql语句在loop内使用collection elements作为bind variables来运行时,就会产生大量的context switchesbulk相关的有2个语法:forallbulk collect

FORALL:将数据打包,一次性从PL/sql引擎发送给sql引擎。

bulk collect:将处理之后的结果集放到bulk collect里,然后一次性把bulk collectsql引擎发送给PL/sql引擎。

因为bulk减少2个引擎之间的context switches,从而提升了sql性能,当要处理的数据量越大,使用bulk和不使用bulk性能区别就越明显。

猜你在找的Oracle相关文章