SQL case-when-else 语句效率
Posted
技术标签:
【中文标题】SQL case-when-else 语句效率【英文标题】:SQL case-when-else statement efficiency 【发布时间】:2016-06-13 08:33:15 【问题描述】:当我使用这个语句时;
UPDATE TABLE
SET FIELD = CASE
WHEN NAME = 'a' THEN (SELECT NO FROM TABLE_TWO WHERE NAME = 'a')
ELSE 'x' END
WHERE FIELD_TWO = 1
如果TABLE.NAME != 'a'
会执行select SQL 吗?
此外,还有一点额外的问题,您认为在任何给定产品的 SQL 代码中都有这样的逻辑是否合适?我认为在 SQL 中包含任何逻辑都会使其覆盖变得非常困难,并且难以维护,您怎么看?
edit:select语句只返回单个值,忽略可以返回多个值的情况,这种情况不在本题讨论范围内。
【问题讨论】:
您使用的是哪个 DBMS?一般来说: CASE 语句没有“快捷方式”,因此很可能会为where
子句选择的每一行执行嵌套选择。但这确实取决于所使用的 DBMS。
目前我使用的是Oracle 12g
【参考方案1】:
The Oracle manual 声称它进行短路评估:
Oracle 数据库使用短路评估。对于一个简单的
CASE
表达式,数据库仅在将每个comparison_expr
值与expr
进行比较之前评估它,而不是在将它们中的任何一个值与expr 进行比较之前评估所有compare_expr 值
在您的情况下,comparison_expr
是 WHEN NAME = 'a'
部分,如果手册正确,如果 name
具有不同的值,数据库将不会运行 select
。
【讨论】:
【参考方案2】:我认为,当您将其拆分为两个这样的 UPDATE 语句时,它会更易于阅读和维护:
UPDATE TABLE SET FIELD = (SELECT TOP 1 NO FROM TABLE_TWO WHERE NAME = 'a')
WHERE FIELD_TWO = 1
AND NAME='a'
UPDATE TABLE SET FIELD = 'x'
WHERE FIELD_TWO = 1
AND NAME != 'a'
它可以让您轻松添加更多案例,如果案例更多,您可以概括案例,例如:
UPDATE TABLE SET FIELD = (SELECT TOP 1 NO FROM TABLE_TWO WHERE NAME = TABLE.FIELD)
WHERE FIELD_TWO = 1
AND NAME IN ('a','b','c')
【讨论】:
我喜欢这个,因为它大大提高了可读性,但即使第一条语句的条件为假,它仍然会执行内部选择,对吧?【参考方案3】:如果我是你,我会使用一个变量,这样这种情况就不会每次都计算一个标量值。类似于以下内容:
DECLARE @myVar VARCHAR(10);
SELECT TOP 1 @myVar = NO FROM TABLE_TWO WHERE NAME = 'a';
UPDATE TABLE
SET FIELD = CASE
WHEN NAME = 'a' THEN @myVar
ELSE 'x' END
WHERE FIELD_TWO = 1
【讨论】:
问题是无论case语句中的条件如何,都会执行select SQL吗?看起来是这样的。以上是关于SQL case-when-else 语句效率的主要内容,如果未能解决你的问题,请参考以下文章