Oracle PL/SQL 过程运行速度比 SQL 慢
Posted
技术标签:
【中文标题】Oracle PL/SQL 过程运行速度比 SQL 慢【英文标题】:Oracle PL/SQL procedure runs slower than SQL 【发布时间】:2015-10-22 17:52:45 【问题描述】:似乎我找到了回答我自己的问题:
首先 - 让我重新提出我的问题:
“在完全相同的环境和条件下”- 一些用户抱怨在几秒钟内运行的同一 SQL 需要一个多小时,而同一 SQL 是 PL/SQL 过程或包的一部分。
这里的关键词是“相同的条件和环境”。 Oracle 版本是 12.1.0.2.0。两者(SQL 和 PL/SQL)的表、行数、操作、统计信息等都是相同的。
这是一个快速测试。
我选择的语句是直接更新 - 所以实际上没有网络或终端显示延迟
-
创建一个包含 200,000 行的表。 (没有任何索引等)。
在服务器级别开启 SQL_TRACE = ON
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,发现显着差异在trace的Execute部分
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 多行,这几秒钟很快就会增加。
这让我想起了汤姆·凯特的名言(不完全是;希望有人能找到链接)
如果你想做某事,用 SQL 来做,
如果 SQL 不合适,那么在 PL/SQL 中做,
如果PL/SQL不适合,那就用Java来做吧,
如果 Java 不适合,则作为外部 C 程序执行,
如果外部 C 不合适,那么想想 - 为什么我们必须首先这样做。
【问题讨论】:
没有更多细节是不可能的。我的猜测是,它实际上不是同一个 SQL 语句,一个使用绑定变量/文字/一个 SQL 配置文件/一个大纲/其他东西,另一个不是。 您希望我们如何回答这样的问题:这里的有用信息为零。您能否就数百万可能导致此问题的事情发表一些疯狂的猜测,但没有更多细节? 当然。这是一个与您问题中的细节一样清楚的答案:当然。您在 PL/SQL 过程中遇到了问题。弄清楚它是什么并修复它。 我们使用的是 oracle 11.2.0.3,标准版。我们没有使用 SQL 配置文件或 SQL 基线。 PL/SQL 使用绑定变量,而 SQL 语句(自然)使用硬编码文字。因此,SQL 是否有可能使用最新的 EXPLAIN 计划,并且由于某种原因,PL/SQL 无法使用最新的 EXPLAIN 计划。 @JustinCave,肯·怀特。问题是“有什么问题?”。有效答案包括“参数转换”、“SQL 和 PL/SQL 引擎之间的上下文切换”。不需要反对票。答案是。 @AlainPannetier - 就目前而言,这个问题过于宽泛,因为实际上有数以千计的可能答案,而且还远远没有足够的信息来确定哪些答案最有可能。 【参考方案1】:不同的提示、会话参数、资源限制、上下文、绑定变量、bug..最好是比较执行计划。
【讨论】:
是的。我比较了执行计划。在 PL/SQL 中花费更多时间的唯一原因是上下文切换。请注意,CPU 时间几乎相同,因为一旦上下文切换完成,部分 CPU 将花费相同的精力来执行它。 通常我希望上下文切换可以在多个语句执行之间看到。所以,循环内的语句左右。如果它只是一次执行和不同的经过时间,可能与上下文切换无关.. 是的 - 我的最终用户正在循环运行 UPDATE - 因此有 100,000 多个上下文切换。即使是几毫秒也会加起来。 感谢您的信息。如果上下文切换是问题,则可能可以考虑批量操作。干杯以上是关于Oracle PL/SQL 过程运行速度比 SQL 慢的主要内容,如果未能解决你的问题,请参考以下文章
为了对存储在 Oracle db 中的数据运行搜索查询,在 PL/SQL 中使用 REGEXP 是不是比在 Java 正则表达式中获取所有数据并过滤它更快?