Performance pl/sql存储过程。。。执行时间到哪里去了?
我目前正在跟踪存储过程中的性能泄漏。 在最初的“开始”之后加上一个时间戳,在最后一个“结束”之前加上一个时间戳(我之前做过一次提交),这说明这个过程大约需要10秒才能完成。 然而,我必须等待2分钟以上,它才能结束 有人能告诉我剩下的时间都到哪里去了吗?我使用的是Oracle SQL dev,但它似乎不会在其余时间处于空闲状态,该过程似乎锁定了相应的表:( 提前非常感谢您的启发 编辑:再次感谢您的输入:) 这是程序的精简代码,取决于要处理的项目数量,第一部分目前大约需要10到40秒,第二部分需要几毫秒。但是,该过程需要2到8分钟才能运行。 此外,包含要删除的数据的表似乎被锁定的时间比需要的时间稍长,从而导致插入延迟。 按计划作业启动它没有什么区别,顺便说一句,相同的行为Performance pl/sql存储过程。。。执行时间到哪里去了?,performance,oracle,stored-procedures,plsql,Performance,Oracle,Stored Procedures,Plsql,我目前正在跟踪存储过程中的性能泄漏。 在最初的“开始”之后加上一个时间戳,在最后一个“结束”之前加上一个时间戳(我之前做过一次提交),这说明这个过程大约需要10秒才能完成。 然而,我必须等待2分钟以上,它才能结束 有人能告诉我剩下的时间都到哪里去了吗?我使用的是Oracle SQL dev,但它似乎不会在其余时间处于空闲状态,该过程似乎锁定了相应的表:( 提前非常感谢您的启发 编辑:再次感谢您的输入:) 这是程序的精简代码,取决于要处理的项目数量,第一部分目前大约需要10到40秒,第二部分需要几
create or replace
procedure MY_PROCEDURE is
start_procedure number;
start_delete number;
end_procedure number;
begin
start_procedure :=dbms_utility.get_time;
begin
-- stripped: doing some selects/updates here
end;
commit;
start_delete :=dbms_utility.get_time ;
begin
-- stripped: cleanig up some other data here
end;
commit;
end_procedure :=dbms_utility.get_time ;
dbms_output.put_line('procedure took: '||to_char((end_procedure- start_procedure)/1000));
dbms_output.put_line('updates took: '||to_char((start_delete- start_procedure)/1000));
dbms_output.put_line('delete took: '||to_char((end_procedure-start_delete)/1000));
end;
我认为需要除以100,而不是1000(dbms_utility.get_time以厘米秒为单位给出时间)。这应该给你100秒,也就是2分钟 但是,如果您想知道2分钟的执行时间到哪里去了,并且取决于过程的复杂性,您可能希望:
- 通过在过程运行之前和之后拍摄快照来收集statspack报告
- 使用PL/SQL分层探查器()李>
Sample Report
Function Elapsed Time (microsecs) Data sorted by Total Subtree Elapsed Time (microsecs)
2831 microsecs (elapsed time) & 12 function calls
Subtree Ind% Function Descendant Ind% Calls Ind% Function Name
2831 100% 93 2738 96.7% 2 16.7% __plsq_vm
2738 96.7% 310 2428 85.8% 2 16.7% __anonymous_block
2428 85.8% 15 2413 85.2% 1 8.3% HR.TEST.TEST (Line 1)
2413 85.2% 435 1978 69.9% 3 25.0% HR.TEST.TEST.FOO (Line 3)
1978 69.9% 1978 0 0.0% 3 25.0% HR.TEST.__static_sql_exec_line5 (Line 5)
0 0.0% 0 0 0.0% 1 8.3% SYS.DBMS_HPROF.STOP_PROFILING (Line 53)
您的时间可能是由于SQL developer刷新您的屏幕时,java和数据库之间有大量的上下文切换。要测试这一点,请在SQLPlus中再次运行测试。要修复此问题,请进入工具>首选项>数据库>高级参数,并将SQL数组获取大小提高到150到500之间的某个值,并且(如果您有合适的驱动程序)勾选“使用OCI/厚驱动程序”框 如果您有合适的PERM(如果没有,请向您的dba寻求帮助),也许您可以查询以下视图:
V$SESSION_WAIT
V$SYSTEM_EVENT
然后可以检查结果
这里($session_wait.htm)*描述了如何读取输出以及其中的事件
*您必须复制url,因为$会弄乱链接。那么是这样的吗
CREATE PROCEDURE ...
AS
DECLARE some stuff
BEGIN
print time
do stuff
COMMIT
print time
END
我对Oracle的事务范例了解不多,但我想知道,在过程完成之前,过程中的提交是否真的没有任何效果,而过程直到结束时才完成。此时,提交事务的实际过程开始了,如果涉及到触发器和引用完整性约束,则可能需要很长时间
这种行为类似于可延迟的初始延迟引用完整性约束的行为
我怀疑建议的系统表查询会告诉您,或者您可以尝试在交互式会话中单步执行“do stuff”步骤,看看会发生什么。声明部分中可能有一些内容需要很长时间才能执行。您能提供存储过程的代码吗?我不熟悉pl/sql,但有没有办法在它运行时暂停或中断它 当它浪费时间时,你击中它的几率等于它浪费时间的百分比,因此你可能需要多次阻止它,以便在行动中抓住它。通常问题是在调用堆栈中间的某个地方。如果可以替换出现在多个堆栈样本上的任何内容,都可以节省大量时间
该程序的作用是什么? 一种可能的解释是DBMS_输出。 如果在SQL*Plus上执行SET SERVEROUTPUT on,则在执行语句后,客户端将“幕后”获取使用DBMS_OUTPUT.PUT_行缓冲的任何信息。我猜SQL开发者也会这么做 因此,如果大量内容被推送到DBMS_输出,那么过程的执行可能会很快,但幕后收集可能会占用时间(特别是在网络速度较慢的情况下) SQL*Plus中的另一个技巧是您可以 设置定时(将自动显示语句的运行时间) 和 将时间设置为ON(在SQL提示符中显示时间) 所以试试看
SET SERVEROUTPUT OFF
SET TIMING ON
SET TIME ON
DBMS_MONITOR.DATABASE_TRACE_ENABLE(TRUE);
exec stored_proc;
disconn
看看结果。我不希望看到任何时间下落不明。也就是说,客户应该报告整整两分钟的时间。
假设是这样,我将使用trace(DBMS_MONITOR命令)并对结果运行tkprof,以查看这2分钟的原因。如果您将对DBMS_utility.get_time的调用替换为以下消息:
dbms_output.put_line ('start procedure: ' || to_char(sysdate, HH24:MI:SS'));
然后调用如下过程:
dbms_output.put_line ('before procedure: ' || to_char(sysdate, HH24:MI:SS'));
exec my_procedure;
dbms_output.put_line ('after procedure: ' || to_char(sysdate, HH24:MI:SS'));
然后,丢失时间发生的地方就会出现。问题解决了,但我仍然不明白 泄漏是由另一个过程调用的另一个过程中隐藏的错误select语句引起的。我优化了它,现在它运行起来很有魅力 我发现了艰难的道路,逐行评论。。。试啊试啊 然而,我仍然想知道为什么时间戳是绝对不准确的。这很容易让人误解,花了我不少时间。。。 那么,我创建时间戳的方式有什么问题吗 如果有人有这方面的消息,我很高兴听到
感谢大家在这个问题上的帮助。在DBMS\u输出语句中,将结果除以1000。根据我在dbms_实用程序中找到的所有Oracle文档,get_time函数以100秒为单位测量时间,而不是1000秒 因此,当您显示10到40秒时,它是actu