嗨,我有一个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子句的索引,效果不大。
答案 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
大小的增加,此查询的性能不应显着下降。
您的帖子中暗示了整个过程中的其他可能的优化方法,但这可能会带给您大部分途径。