似乎我找到了回答我自己的问题:
首先 - 让我重新提出我的问题:
"在完全相同的环境和条件下" - 有些用户抱怨在几秒钟内运行的同一个SQL需要花费一个多小时,而同一个SQL是PL / SQL过程或包的一部分。
这里的关键词是"相同的条件和环境"。 Oracle版本是12.1.0.2.0。 (SQL和PL / SQL)的表,行计数,操作,统计等都是相同的。
这是一个快速测试。
我选择的陈述是直接更新 - 所以几乎没有网络或终端显示延迟
SQL: 一个。更新统计数据 湾
设定时间Update TABLE_1 set Character_Col = 'XXXX';
PL / SQL:
一个。更新统计信息
create or replace procedure upd_tab as
begin
update TABLE_1 set Character_Col = 'XXXX';
dbms_output ( .. print SQL%ROWCOUNT etc. );
end;
比较TRACE时,在跟踪的执行部分
中发现了显着差异SQL:
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Execute 1 2.19 2.40 0 1902 257114 200000
PL / SQL:
call count cpu elapsed disk query current rows
Execute 1 2.13 5.94 0 1884 256912 200000
所以 - 我能理解的是当PL / SQL向SQL发送语句时会发生CONTEXT-SWITCHING。当语句直接作为SQL执行时,则不涉及上下文切换。
似乎我的最终用户正在使用游标一次从存储过程向数据库发送一个UPDATE语句。对于超过100,000行,这几秒钟很快就会加起来。
它让我想起Tom Kyte的名言(不完全是;希望有人能找到这个链接)
如果你想做某事,可以在SQL中进行,
如果SQL不合适,那么在PL / SQL中执行,
如果PL / SQL不适合,则将其作为Java,
如果Java不适合,则将其作为外部C程序,
如果外部C不适合,那么请考虑 - 为什么我们必须首先做到这一点。
答案 0 :(得分:1)
不同的提示,会话参数,resurce限制,上下文,绑定变量,bug ..最好是比较执行计划。