oracle 12c存储过程在循环中运行时增加了执行时间

时间:2018-08-28 02:14:20

标签: oracle performance stored-procedures plsql

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

应用程序具有存储的proc,该存储的proc存在间歇性的性能问题。

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

我以100的循环运行存储的proc,我发现它以74毫秒的执行时间开始,在第100循环的结尾,该过程的执行时间约为5000毫秒。

正在寻找为什么会这样的指针?

proc中的查询类似于

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

在这种情况下,Oracle没有为同一查询执行创建多个计划。 我已经将优化器模式设置为first_rows,并且还验证了where子句的索引,效果不大。

2 个答案:

答案 0 :(得分:0)

如果您未在循环内提​​交,则观察到的原因可能是由于在Rollback segment(s)中记录交易花费的时间越来越长。

但是通常,您应该避免在PL / SQL中运行循环。仅通过SQL查询以及Oracle(而不是您)处理的“循环”就可以实现良好的性能。

答案 1 :(得分:0)

TAB是否正在增长(也就是说,您发布的INSERT INTO TAB的执行之间有什么事情SELECT在执行)?如果是这样,很明显,如果SELECT正在对TAB进行全表扫描,为什么它会变慢。随着TAB的增长,这将花费越来越长的时间。

如果您在INDEX列上有一个c,请尝试通过以下方式重写SELECT

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

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

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

您的帖子中暗示了整个过程中的其他可能的优化方法,但这可能会带给您大部分途径。