sql比oracle中的plsql快吗

Bis*_*ain 0 sql plsql bulkinsert oracle11g query-performance

使用批量收集或常规合并更新?

我试图通过使用批量收集和正常合并来检查更新的性能。我看到当我们在匿名块中使用简单合并时,性能会更好。使用批量收集时,需要花费更多时间。

如果正常更新(合并)比批量收集快,那么为什么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;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)

我在合并查询中得到0.797秒,对批量收集得到171.352秒

Jus*_*ave 7

如果您可以在SQL中执行此操作,那么在SQL中执行此操作几乎总是更有效。如果您必须执行PL / SQL,因为您要执行一些得益于过程代码的处理,那么a bulk collect和a forall会比旧式逐行处理更为有效(尽管如果您使用的是隐式游标, Oracle的最新版本将bulk collect在幕后自动执行操作,因此差异不会像以前那么大)。

在您的测试中,我希望循环中的提交能够解决运行时中的大部分差异。显然,这在功能上与SQL解决方案有所不同。

  • 总体而言,同意贾斯汀的观点。但是,我想更全面地解释以下评论:“(尽管您使用的是隐式游标,但Oracle的最新版本将在幕后自动进行批量收集,因此差异不大。) ” (1)如果您正在执行游标FOR循环,并且在其中执行逐行DML(插入,更新,删除),Oracle将自动优化CFL以在每次提取时返回100行。这类似于FETCH-BULK COLLECT-LIMIT100。但是实际上并没有将其重新编码为BULK COLLECT语句。到那时它已经在C代码中了。:-) (3认同)