在 oracle 中 sql 比 plsql 快
is sql faster than plsql in oracle
使用批量收集或正常合并更新?
我正在尝试使用批量收集和正常合并来检查更新的性能。
我看到当我们在匿名块中使用简单合并时性能更好。
当我使用批量收集时,它需要更多时间。
如果正常更新(合并)比批量收集快,那为什么oracle引入了它?我们在哪里真正看到批量收集的好处?
declare
l_start integer;
l_end integer;
begin
l_start := dbms_utility.get_time;
merge into test111 t1
using test112 t2
on (t1.col1 = t2.col3)
when matched then update
set t1.col2 = t1.col2*5;
l_end := dbms_utility.get_time;
dbms_output.put_line(l_end - l_start);
end;
declare
type nt_test is table of test112.col3%TYPE;
nt_val nt_test := nt_test();
cursor c is select col3 from test112;
c_limit integer := 100;
l_start integer;
l_end integer;
begin
l_start := DBMS_UTILITY.get_time;
open c;
loop
fetch c
bulk collect into nt_val limit c_limit;
exit when nt_val.count = 0;
forall i in indices of nt_val
update test111 set col2 = col2/ 5
where col1 = nt_val(i);
commit;
end loop;
l_end := dbms_utility.get_time;
dbms_output.put_line(l_end - l_start);
end;
我在合并查询中得到 0.797 秒,在批量收集中得到 171.352 秒
如果您可以在 SQL 中完成,那么在 SQL 中几乎总是更有效率。如果你不得不求助于 PL/SQL 因为你正在做一些受益于过程代码的处理,那么做一个 bulk collect
和一个 forall
将比旧式逐行更有效 -行处理(尽管如果您使用隐式游标,最新版本的 Oracle 将在幕后自动执行 bulk collect
,因此差异没有以前那么大)。
在您的测试中,我希望循环中的提交能够解释运行时的大部分差异。显然,这在功能上不同于 SQL 解决方案。
如果你能在 SQL 内完成,它总是会更快,但即便如此,171.352 也是非常高的价值。所以我做了我的测试,我在 test111(col1) 上添加了一个索引,并且在 0.20 秒内完成了相同的 pl/sql 块。
使用批量收集或正常合并更新?
我正在尝试使用批量收集和正常合并来检查更新的性能。 我看到当我们在匿名块中使用简单合并时性能更好。 当我使用批量收集时,它需要更多时间。
如果正常更新(合并)比批量收集快,那为什么oracle引入了它?我们在哪里真正看到批量收集的好处?
declare
l_start integer;
l_end integer;
begin
l_start := dbms_utility.get_time;
merge into test111 t1
using test112 t2
on (t1.col1 = t2.col3)
when matched then update
set t1.col2 = t1.col2*5;
l_end := dbms_utility.get_time;
dbms_output.put_line(l_end - l_start);
end;
declare
type nt_test is table of test112.col3%TYPE;
nt_val nt_test := nt_test();
cursor c is select col3 from test112;
c_limit integer := 100;
l_start integer;
l_end integer;
begin
l_start := DBMS_UTILITY.get_time;
open c;
loop
fetch c
bulk collect into nt_val limit c_limit;
exit when nt_val.count = 0;
forall i in indices of nt_val
update test111 set col2 = col2/ 5
where col1 = nt_val(i);
commit;
end loop;
l_end := dbms_utility.get_time;
dbms_output.put_line(l_end - l_start);
end;
我在合并查询中得到 0.797 秒,在批量收集中得到 171.352 秒
如果您可以在 SQL 中完成,那么在 SQL 中几乎总是更有效率。如果你不得不求助于 PL/SQL 因为你正在做一些受益于过程代码的处理,那么做一个 bulk collect
和一个 forall
将比旧式逐行更有效 -行处理(尽管如果您使用隐式游标,最新版本的 Oracle 将在幕后自动执行 bulk collect
,因此差异没有以前那么大)。
在您的测试中,我希望循环中的提交能够解释运行时的大部分差异。显然,这在功能上不同于 SQL 解决方案。
如果你能在 SQL 内完成,它总是会更快,但即便如此,171.352 也是非常高的价值。所以我做了我的测试,我在 test111(col1) 上添加了一个索引,并且在 0.20 秒内完成了相同的 pl/sql 块。