【问题标题】:Oracle Procedure with Array param vs fixed param performance具有数组参数的 Oracle 过程与固定参数性能
【发布时间】:2015-03-06 21:31:18
【问题描述】:

我想知道如果我调用具有 n 个值的数组的过程与调用 n 次只接受一个并行参数的过程对性能的影响。

我不是数据库开发人员,但我们团队中的数据库开发人员说,当您运行带有单个参数的过程时,运行速度比带有单个元素的数组参数的过程要快。所以我在一个耗时的 SP 上测试了这个理论,结果证明是正确的。

这里发生了什么?有人可以解释吗?它是通用的还是只是 DATA 模型特定的结果。

非常感谢您的帮助,因为我们必须提高系统的性能,但要确定一些长期运行的 SP。

卡皮尔

【问题讨论】:

  • 你有一些测试用例代码可以分享来证明这个问题吗?
  • @TonyAndrews,感谢您抽出宝贵的时间和兴趣。我没有可以轻松演示的东西,因为该过程本身就像 2000 多行,而且它是公司专有的表/数据,所以我很难重新创建场景。

标签: oracle plsql database-performance


【解决方案1】:

您可能希望坚持使用数组参数。与组合操作的好处相比,支持多个值的额外开销无关紧要。

批处理操作是数据库性能的关键。以集合、块、批量等方式执行操作通常比逐行处理快几个数量级。我经常看到成百上千的 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;
/

【讨论】:

  • 谢谢乔恩,感谢您的解释。这是一个很好的起点,我可以在 DB 开发人员的帮助下进行调查并了解查询计划的外观。将 Array 作为参数是否会对查询计划产生任何影响?
猜你喜欢
  • 2020-12-15
  • 1970-01-01
  • 2021-11-28
  • 2018-02-27
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
  • 2018-05-31
  • 2013-06-14
相关资源
最近更新 更多