为什么在 MS Sql 服务器的 Where 子句中使用 CASE 语句
Why CASE statement in Where clause for MS Sql server
在 MS SQL Server 2012 中对第 3 方供应商系统进行一些性能调整。
他们做了很多像这样的 where 子句:
WHERE
(
CASE
WHEN @searchID = '' THEN 1
WHEN ((C.SAPCustomerNumber = @searchID ) OR (C.SAPCustomerNumber = @SapID)) THEN 1
ELSE 0
END = 1
)
除了混淆查询计划之外,where 子句中的 Case 1 或 0 有什么好处?
谢谢
到目前为止,出现此类代码的最常见原因是有人不熟悉 SQL、CASE
表达式或两者。他们不知何故开始关注 CASE
并决定它应该用于所有条件评估。
这通常是一个错误,可以用更简单的布尔逻辑替换,正如@Bogdan 在评论中建议的那样:
((C.SAPCustomerNumber = @searchID ) OR (C.SAPCustomerNumber = @SapID) OR (@searchID = '' ))
可以这样做的第二个原因是如果有人试图强制执行谓词的评估顺序1。 CASE
被记录为按顺序评估其 WHEN
条件(前提是它们是标量表达式,而不是聚合)。不过,我真的不建议任何人实际编写这样的代码——它很容易被误认为是第一种形式。即使特定的评估顺序在今天是最好的,根据今天的数据,谁又能说它明天、一个月或几年后是否仍然正确?
1SQL 一般不保证 WHERE
子句谓词的任何求值顺序,也不保证任何形式的短路求值。优化器通常可以自由地重新排序谓词 - 在 WHERE
子句和 JOIN
/ON
子句中 - 以尽可能便宜地获得整体结果。通常,您不应该试图阻止它这样做。
如果它没有选择最有效的计划,那么通过 updating/creating 索引和统计信息或实际强制执行特定计划可以更好地解决这个问题,而不是使用 CASE
.
在 MS SQL Server 2012 中对第 3 方供应商系统进行一些性能调整。
他们做了很多像这样的 where 子句:
WHERE
(
CASE
WHEN @searchID = '' THEN 1
WHEN ((C.SAPCustomerNumber = @searchID ) OR (C.SAPCustomerNumber = @SapID)) THEN 1
ELSE 0
END = 1
)
除了混淆查询计划之外,where 子句中的 Case 1 或 0 有什么好处?
谢谢
到目前为止,出现此类代码的最常见原因是有人不熟悉 SQL、CASE
表达式或两者。他们不知何故开始关注 CASE
并决定它应该用于所有条件评估。
这通常是一个错误,可以用更简单的布尔逻辑替换,正如@Bogdan 在评论中建议的那样:
((C.SAPCustomerNumber = @searchID ) OR (C.SAPCustomerNumber = @SapID) OR (@searchID = '' ))
可以这样做的第二个原因是如果有人试图强制执行谓词的评估顺序1。 CASE
被记录为按顺序评估其 WHEN
条件(前提是它们是标量表达式,而不是聚合)。不过,我真的不建议任何人实际编写这样的代码——它很容易被误认为是第一种形式。即使特定的评估顺序在今天是最好的,根据今天的数据,谁又能说它明天、一个月或几年后是否仍然正确?
1SQL 一般不保证 WHERE
子句谓词的任何求值顺序,也不保证任何形式的短路求值。优化器通常可以自由地重新排序谓词 - 在 WHERE
子句和 JOIN
/ON
子句中 - 以尽可能便宜地获得整体结果。通常,您不应该试图阻止它这样做。
如果它没有选择最有效的计划,那么通过 updating/creating 索引和统计信息或实际强制执行特定计划可以更好地解决这个问题,而不是使用 CASE
.