为什么在MS Sql server的Where子句中使用CASE语句

时间:2015-08-05 11:52:42

标签: sql-server sql-server-2012 case

在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有什么优势?

由于

1 个答案:

答案 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,可以更好地解决此问题。