今天看了一個2010年發的一個貼子。記錄一下動態使用FORALL語句與FOR的性能對比,測試環境爲ORACLE 10G
1.建立二個表
create table a_tab(ver number,id number)
A_tab表中寫了20000條記錄;
create table b_tab(ver number,id number)
B_tab表中無記錄;
2.給a_tab表增加數據;
declare
l_add integer:=0;
begin
for i in 1..20000 loop
l_add:=l_add+1;
execute immediate 'insert into a_tab values(:a,:b)' using i,l_add;
end loop;
commit;
end;
/
PL/SQL procedure successfully completed
Executed in 2.172 seconds
SQL> select count(*) from a_tab;
COUNT(*)
----------
20000
Executed in 0.031 seconds
下面這段代碼爲不知道表名插入數據,使用FORALL語句實現
declare
v_sql varchar2(4000);
v_tablename varchar2(100):='b_tab';
begin
v_sql:='
declare
type r_outtab is record (ver NUMBER,id NUMBER);
type t_outtab is table of r_outtab index by binary_integer;
v_outtab t_outtab;
v_query varchar2(30000);
begin
v_query :=''select ver,id from a_tab '' ;
execute immediate v_query bulk collect into v_outtab;
forall i in v_outtab.first .. v_outtab.last
insert into '||v_tablename||' values v_outtab(i) ;
end;';
dbms_output.put_line(v_sql);
execute immediate v_sql;
commit;
end;
/
PL/SQL procedure successfully completed
Executed in 0.203 seconds
PL/SQL procedure successfully completed
Executed in 0.125 seconds
以上是二次插入時間
SQL> select count(*) from b_tab;
COUNT(*)
----------
20000
Executed in 0.015 seconds
下面這段代碼爲FOR語句實現
declare
type r_outtab is record(
ver NUMBER,
id NUMBER);
type t_outtab is table of r_outtab index by binary_integer;
v_outtab t_outtab;
v_tablename varchar2(100);
v_query varchar2(30000);
begin
v_tablename := 'b_tab';
v_query := 'select ver,id from a_tab ';
execute immediate v_query bulk collect into v_outtab;
for i in v_outtab.first .. v_outtab.last loop
execute immediate 'insert into ' || v_tablename || ' values(:a, :b)' using v_outtab(i).ver, v_outtab(i).id;
end loop;
end;
/
PL/SQL procedure successfully completed
Executed in 10.906 seconds
PL/SQL procedure successfully completed
Executed in 27.063 seconds
以上二次插入數據
SQL> select count(*) from b_tab;
COUNT(*)
----------
60000
Executed in 0.078 seconds
通過二次對比,使用FORALL的動態SQL比FOR的插入要快
但是FORALL不支持下面語句請大家注意,使用按上面的例子使用
declare
type r_outtab is record (ver NUMBER,id NUMBER);
type t_outtab is table of r_outtab index by binary_integer;
v_outtab t_outtab;
v_query varchar2(30000);
v_tablename varchar2(100):='a_tab';
begin
v_query :='select ver,id from b_tab ' ;
execute immediate v_query bulk collect into v_outtab;
forall i in v_outtab.first .. v_outtab.last
execute immediate 'insert into '||v_tablename||' values (:a,:b)' using v_outtab(i).ver,v_outtab(i).id ;
end;
ORA-06550: line 13, column 82:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
ORA-06550: line 13, column 11:
PL/SQL: Statement ignored
ORA-06550: line 13, column 11:
PLS-00435: DML statement without BULK In-BIND cannot be used inside FORALL