【问题标题】:oracle 12c stored procedure increasing execution time when run in a looporacle 12c存储过程在循环中运行时会增加执行时间
【发布时间】:2019-02-02 13:45:24
【问题描述】:

您好,我有一个 Oracle 12c 数据库,总 SGA 为 12 GB,共享池区域目标设置为 4 GB。

应用程序有一个存储过程,观察到它存在间歇性性能问题。

已确定存储过程所采用的执行路径,并且该路径上的单个查询对其具有低成本计划。

我在 100 次循环中运行存储过程,我看到它以 74 毫秒的执行时间开始,在第 100 次循环结束时,该过程的执行时间约为 5000 毫秒。

寻找关于为什么会这样的指针?

proc 中的查询类似于

 SELECT a, b
  FROM (  SELECT a, b
            FROM tab
        ORDER BY c)
 WHERE ROWNUM = 1;

Oracle,正如在这种情况下所观察到的,没有为同一个查询执行创建多个计划。 我已将优化器模式设置为 first_rows 并验证了 where 子句上的索引,但没有太大影响。

【问题讨论】:

  • 请提供存储过程的代码sn-p以供同行审阅,可以通过编辑问题来实现。
  • 间歇性性能问题是最难诊断的,如果没有更多信息,远程诊断是不可能的。几乎可以肯定,问题不在于您发布的查询,而是与您的存储过程所做的其他事情有关。如果您需要一些具体建议,您必须发布更多详细信息。

标签: oracle performance stored-procedures plsql


【解决方案1】:

TAB 是否在增长(即,在您发布的 SELECT 的执行之间,INSERT INTO TAB 是否在做任何事情)?如果是这样,那么如果SELECT 正在对TAB 进行全表扫描,那么它为什么会变慢就很清楚了。随着TAB 的增长,这将需要越来越长的时间。

如果您在c 列上有INDEX,请尝试以这种方式重写您的SELECT

SELECT a, b 
FROM (  SELECT a, b
        FROM tab
        WHERE c = ( SELECT min(c) FROM tab )
        ORDER BY c)
WHERE ROWNUM = 1;

该索引将允许 Oracle 使用 INDEX FULL SCAN (MIN/MAX) 访问方法非常快速地找到 min(c)。然后,将通过INDEX RANGE SCAN 访问使用相同的索引非常快速地查找该最小值。

随着TAB 大小的增加,此查询的性能不会显着下降。

您的帖子暗示了整个过程中其他可能的优化,但这可能会让您大部分时间到达您想要的位置。

【讨论】:

    【解决方案2】:

    如果您没有在循环内提​​交,您观察到的可能是由于在Rollback segment(s) 中记录您的事务需要越来越多的时间。

    但总的来说,您应该避免在 PL/SQL 中运行循环。单独使用 SQL 查询可以获得良好的性能,而“循环”由 Oracle 处理,而不是您。

    【讨论】:

    • 我认为循环中的运行只是指 OP 用于收集时间的测试工具,而不是其存储过程的内部。
    猜你喜欢
    • 2020-01-05
    • 1970-01-01
    • 2017-10-07
    • 2017-06-10
    • 2020-10-11
    • 2019-11-27
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    相关资源
    最近更新 更多