[英]PLSQL Performance Issue
这更多的是怀疑而不是问题。 我只需要从一个表中选择一些通用字段,然后将其插入到另一个表中。 我用2种不同的样式完成了代码,但都使用BULK COLLECT。 哪个是更好的选择,或者除此之外还有其他方法吗?
请在下面找到必要的详细信息。
create or replace procedure a2 is
cursor c1 is select id,address from emp1;
type t is table of c1%rowtype;
c t;
begin
open c1;
loop
fetch c1 bulk collect into c;
exit when c.count=0;
forall j in 1..c.count save exceptions
insert into empl1(id,address) values (c(j).id,c(j).address);
end loop;
commit;
exception when others then
for j in 1..sql%bulk_exceptions.count loop
dbms_output.put_line('The sql error is error occured');
end loop;
end a2;
/
运行以上过程并输出:
declare
a number;
begin
dbms_output.put_line ('before procedure: ' || to_char(sysdate, 'HH24:MI:SS'));
a2;
dbms_output.put_line ('after procedure: ' || to_char(sysdate, 'HH24:MI:SS'));
end;
before procedure: 23:44:48
after procedure: 23:45:47
PL/SQL procedure successfully completed.
因此,以上过程花费了59秒来插入34801020记录。
现在,请找到第二个步骤。
create or replace procedure a3 is
cursor c1 is select id,address from emp1;
type t is table of c1%rowtype;
c t;
begin
select id,address bulk collect into c from emp1;
forall j in 1..c.count save exceptions
insert into empl1(id,address) values (c(j).id,c(j).address);
exception when others then
for j in 1..sql%bulk_exceptions.count loop
dbms_output.put_line('The sql error is error occured');
end loop;
end a3;
/
使用output运行上述过程。
declare
a number;
begin
dbms_output.put_line ('before procedure: ' || to_char(sysdate, 'HH24:MI:SS'));
a3;
dbms_output.put_line ('after procedure: ' || to_char(sysdate, 'HH24:MI:SS'));
end;
before procedure: 23:47:57
after procedure: 23:48:53
PL/SQL procedure successfully completed.
该过程花费了56秒来插入34801020记录。
SQL> select count(1) from emp1;
COUNT(1)
----------
34801020
以上两种方法中的哪一种是将3百万条记录插入表中的最佳方法,如果有其他更好的方法可以完成上述插入过程,请告诉我。
我使用具有相似数据集大小的相似代码运行了测试
使用游标循环
create or replace procedure a2 is
cursor c1 is select empno,ename from bigemp;
type t is table of c1%rowtype;
c t;
begin
open c1;
loop
fetch c1 bulk collect into c;
exit when c.count=0;
forall j in 1..c.count save exceptions
insert into bigemp2(empno,ename) values (c(j).empno,c(j).ename);
end loop;
commit;
exception when others then
for j in 1..sql%bulk_exceptions.count loop
dbms_output.put_line('The sql error is error occured');
end loop;
end a2;
SQL> exec a2
PL/SQL procedure successfully completed.
Elapsed: 00:00:56.93
执行常规的插入语句,而不使用cursor-for循环
SQL> insert into bigemp2( empno, ename )
select empno, ename from bigemp t2
29360128 rows created.
Elapsed: 00:00:11.30
现在执行直接路径插入
SQL> insert /*+ append */ into bigemp2( empno, ename )
select empno, ename from bigemp t2
;
29360128 rows created.
Elapsed: 00:00:06.01
添加一些并行性
SQL> alter session enable parallel dml;
Session altered
SQL> insert /*+ append parallel(2 ) */ into bigemp2( empno, ename )
select /* parallel( t2, 2 ) */ empno, ename from bigemp t2
;
29360128 rows created.
Elapsed: 00:00:03.52
因此,总而言之,仅通过使用适当的技术,我们就可以使处理过程和数量级加快(快大约16倍)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.