ORACLE 中的 PL/SQL、IF-ELSE 或 SELECT DECODE 哪个更好

Posted

技术标签:

【中文标题】ORACLE 中的 PL/SQL、IF-ELSE 或 SELECT DECODE 哪个更好【英文标题】:Which is better for PL/SQL, IF-ELSE OR SELECT DECODE IN ORACLE 【发布时间】:2017-12-13 09:02:27 【问题描述】:

我正在考虑在我的 pl/sql 函数中将 if 块转换为解码。由于我们不能直接在 pl/sql 中使用 decode,因此计划是使用 'select decode() into variable from dual'。现有的if块如下:

if var1 = 'a' then
 var2 := 'x';

elseif var1 = 'b' then
 var2 := 'y';

else
 var2 := 'z';

end if;

替换解码可能是:

 select decode(var1,'a','x','b','y','z') into var2 from dual;

解码可以显着减少代码行(对于类似的较大块),但这是更好的方法吗?

【问题讨论】:

CASE 的效果同样出色且易于理解。您可以使用CASE 语句代替DECODE 视情况而定。但在你的例子中,这是个坏主意。当从 plsql 调用 sql 时,oracle 正在更改上下文。 (这称为上下文切换)。这是非常流行的性能错误。 更便于人类理解和维护?要移植到下一个版本的 Oracle 或其他 SQL 产品?解析器解析?让优化器优化? 一般来说,你应该避免解码。在 SQL 和 PL/SQL 中都使用 CASE。当然在 PL/SQL 中,不要在不需要时向 SQL 引入上下文切换。我写了一篇博客文章探索 PL/SQL 中条件逻辑的选项。可能在这里有用。 stevenfeuersteinonplsql.blogspot.com/2017/10/… 【参考方案1】:

在 Oracle PLSQL 块中,有 2 种类型的引擎可以工作。第一个 SQL 引擎和另一个 PLSQL 引擎。每当您在PLSQL 块中编写SQL 语句时,就会发生引擎切换,这种现象称为Context 切换。上下文切换越多,应用程序的性能就越差。

当你这样做时:

if var1 = 'a' then
 var2 := 'x';

elseif var1 = 'b' then
 var2 := 'y';

else
 var2 := 'z';

end if;

该语句在PLSQL 引擎中进行评估,并且不会发生上下文切换。但是当你这样做时:

begin
select decode(var1,'a','x','b','y','z') into var2 from dual;
end;

PLSQL 引擎将控制更改为 SQL 引擎并发生上下文切换。所以这个操作会降低性能。

【讨论】:

【参考方案2】:

我认为第一种方法更好。

因为不需要通过dual 查询产生额外的开销,尤其是在大型应用程序中。我的意思是不需要为可以在应用程序内部解决的问题应用数据库。如果您查看执行计划,您会看到成本值为 2,用于查询 dual 表。

顺便说一下,这对于数据库和应用服务器之间的网络来说是一个额外的负载。

【讨论】:

以上是关于ORACLE 中的 PL/SQL、IF-ELSE 或 SELECT DECODE 哪个更好的主要内容,如果未能解决你的问题,请参考以下文章

oracle 的 PL/SQL 中的 & 和 : 有啥区别?

PL/SQL:ORACLE 中的感叹号

Oracle:使用 SQL 或 PL/SQL 查找动态 SQL 中的错误位置

Oracle Apex:PL/SQL 块中的 Javascript 代码

Oracle 12c - PL/SQL 中的问题

用于 oracle 11g 的 PL/SQL 中的嵌入式脚本 [重复]