--建立基础表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/
,如需转载,请注明出处,否则将追究法律责任。