ITPub博客

首页 > Linux操作系统 > Linux操作系统 > BULK COLLECT和FORALL联合使用没有提高性能?

BULK COLLECT和FORALL联合使用没有提高性能?

原创 Linux操作系统 作者:sr1983 时间:2013-03-11 20:13:12 0 删除 编辑
--建立基础表test1
create table test1
(id varchar2(20),name varchar2(20));

--建立基础表test2
create table test2 as select * from test1;

--插入100万条数据
declare
j number(20):=0;
begin
       for i in 1..1000000 loop
           insert into test1 values(i,'RUI'||i);
           j:=i+1;
           if mod(i,100)=0 then
              commit;
           end if;
       end loop;
       commit;
end;
 

总结出以下三种BULK COLLECT及FORALL的写法。
-----------------------------------------------------------------------------------
--BULK COLLECT(第一种写法)
declare
  type idname_tab is table of test1%rowtype;
  cf_idname idname_tab;
begin
  select id, name bulk collect into cf_idname from test1;
  forall i in cf_idname.first .. cf_idname.last
    insert into test2 values cf_idname (i);
  commit;
exception
  when others then
    rollback;
end;

--BULK COLLECT(第二种写法)
declare
  sql_code  varchar2(200);
  sql_errom varchar2(200);
  type idname_tab is table of test1%rowtype;
  cf_idname idname_tab;
  cursor cur is
    select id, name from test1;
begin
  open cur;
  fetch cur bulk collect
    into cf_idname;
  close cur;
  forall i IN INDICES OF cf_idname
    insert into test2 values cf_idname (i);
  commit;
exception
  when others then
    sql_code  := sqlcode;
    sql_errom := SQLERRM;
    rollback;
end;


--BULK COLLECT(第三种写法)
declare
  sql_code  varchar2(200);
  sql_errom varchar2(200);
  type id_tab is table of test2.id%type;
  id_value id_tab;
  type name_tab is table of test2.name%type;
  name_value name_tab;
begin
  delete from test2
  returning id, name bulk collect into id_value, name_value;
  FOR i IN id_value.first .. id_value.last LOOP
    dbms_output.put_line(id_value(i));
    dbms_output.put_line(name_value(i));
  END LOOP;
  ROLLBACK;
EXCEPTION
  WHEN OTHERS THEN
    sql_code  := sqlcode;
    sql_errom := SQLERRM;
    ROLLBACK;
end;
------------------------------------------------------------------
  
思考的问题,没法通过BULK COLLECT来提高删除的效率。
如:truncate table test2;
执行多次,直至TEST2到2千万条数据。
insert /*+ append */ into test2 select * from test1;
commit;

如何提高删除的效率?
现在需要根据TEST1的id去删除TEST2的数据,但是发现这样做提高不了删除的速度,BULK COLLECT后会使内存溢出,难道 BULK COLLECT出数据后,内存不能马上释放吗?我怎样快速删除TEST2表的数据(该表有2千万条)
declare
type id_tab is table of test2.id%type;
id_values  id_tab;
cursor id_test1 is select id from test2;
begin
 loop
      FETCH id_test1 BULK COLLECT INTO  id_values LIMIT 10000;-- 之前没 有LIMIT限制的行数,后来加的,但还是很慢
          EXIT WHEN  id_test1%NOTFOUND;

      FORALL id_del IN 1 ..  id_values .COUNT
        DELETE FROM test2 WHERE id=  id_values(i_del2);
    commit;                                         
    end loop;
    close  id_test1;
end;

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

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2012-06-25

  • 博文量
    1
  • 访问量
    1688