如果我使用n个值的数组调用一个过程,而不是一个只接受一个param的过程调用n次,我想知道性能影响。
我不是数据库开发人员,但我们团队中的数据库开发人员表示,当您使用单个参数运行程序时,运行速度比使用包含单个元素的数组参数的程序快。所以我在一个耗时的SP上测试了这个理论,结果证明是真的。
这里发生了什么?谁能解释一下?它是通用的还是仅仅是DATA Model特定的结果。
非常感谢帮助,因为我们必须提高系统的性能,但要确定一些长期运行的SP。
卡皮尔西
答案 0 :(得分:2)
您可能希望坚持使用数组参数。与组合操作的好处相比,支持多个值的额外开销是无关紧要的。
批处理操作是数据库性能的关键。以集合,块,批量等方式执行操作通常比逐行处理快几个数量级。我经常看到数百个JVM难以一次一行地每分钟处理几兆字节。而且我经常看到一个查询很容易处理每分钟几千兆字节。
这有一些例外。有些系统一切都是一次完成的。在那些情况下,你不必担心这种琐事。我去过那里很痛苦。它导致了一些荒谬的变化,比如replacing functions with procedures,因为在某些情况下它们可以无限快地变化。在这种情况下,开始考虑完全重写。
传递多个值应该要快得多。它可以减少过程调用的次数(减少网络流量,查询解析等)。它可以使您使用批量收集和FORALL
等功能(解析较少,SQL和PL / SQL之间的上下文切换较少等)。
但是如果你担心调用琐碎程序的开销数百万次,那么是的,使用数组会慢几倍。在下面的例子中, 使用复合数据类型需要28秒,而原始数据类型需要7秒。
declare
v_number number := 1;
v_numbers sys.odcinumberlist := sys.odcinumberlist(1);
v_number_out number;
procedure one_parameter(p_value in number, p_return out number) is
begin
p_return := p_value+1;
end;
procedure many_parameters(p_value in sys.odcinumberlist, p_return out number) is
v_number number;
begin
p_return := p_value(1)+1;
end;
begin
--10M: 7.035
--10M: 7.004
for i in 1 .. 100000000 loop
--Using predefined variables:
--one_parameter(v_number, v_number_out); -- 7.0035 seconds
--many_parameters(v_numbers, v_number_out); -- 7.004 seconds
--Passing in values:
--one_parameter(1, v_number_out); -- 7.161 seconds
many_parameters(sys.odcinumberlist(1), v_number_out); -- 27.877 seconds
end loop;
--Make sure the number is used so it won't be optimized away.
dbms_output.put_line(v_number_out);
end;
/