在MS SQL Server 2012中的第三方供应商系统上进行一些性能调整。
他们做了很多这样的条款:
WHERE
(
CASE
WHEN @searchID = '' THEN 1
WHEN ((C.SAPCustomerNumber = @searchID ) OR (C.SAPCustomerNumber = @SapID)) THEN 1
ELSE 0
END = 1
)
除了混淆查询计划之外,where子句中的案例1或0有什么优势?
由于
答案 0 :(得分:4)
到目前为止,最常见的导致此类代码出现的原因是对SQL,CASE
表达式或两者都不熟悉的人。他们以某种方式注意CASE
并决定它应该用于所有条件评估。
这通常是一个错误,可以用更简单的布尔逻辑替换,正如@Bogdan在评论中建议的那样:
((C.SAPCustomerNumber = @searchID ) OR (C.SAPCustomerNumber = @SapID) OR (@searchID = '' ))
可以完成的第二个原因是,有人试图强制执行谓词 1 的评估顺序。记录CASE
以按顺序评估其WHEN
条件(假设它们是标量表达式,而不是聚合)。我真的不建议任何人真正编写这样的代码 - 但它很容易被误认为是第一种形式。即使一个特定的评估订单今天最好,有了今天的数据,谁能说它明天仍然是正确的,还是一个月或几年的时间?
1 SQL不保证WHERE
子句谓词的任何评估顺序,也不保证任何形式的短路评估。优化器通常可以自由地重新排序谓词 - 在WHERE
子句和JOIN
/ ON
子句中 - 以尽可能便宜地尝试实现整体结果。一般来说,你不应该试图阻止它这样做。
如果它没有选择最有效的计划,通过更新/创建索引和统计数据或实际强制执行特定计划,而不是使用CASE
,可以更好地解决此问题。