这些过滤方法之间的性能是否存在差异?
Method 1: WHERE (@Col1 IS NULL OR t.column = @Col1)
Method 2: WHERE 1 = case when @col1 is null then 1 else case when col1 = @col1 then 1 else 0 end end
答案 0 :(得分:2)
为什么不使用Coalesce?
Where Col1 = Coalesce(@Col1, Col1)
编辑:(请参阅下面的Joel评论)仅当col1不允许Null时,或者如果它允许空值并且您希望在@ Col1为空或不存在时排除空值,则此方法有效。因此,如果它允许空值,并且当@ Col1参数为空或不存在时,您希望它们 包含 ,则修改如下:
Where Coalesce(@Col1, Col1) Is Null Or Col1 = Coalesce(@Col1, Col1)
答案 1 :(得分:2)
如果您知道Col1列本身不包含任何空值,则可以执行以下操作:
WHERE Col1 = COALESCE(@Col1, Col1)
否则,您的CASE语句通常比OR好一点。我强调“典型”,因为表格不同。你应该总是知道如何确定。
不幸的是,通常最快的方式是使用动态sql,如果参数为null,则首先从查询中排除条件。但当然可以将其视为最后的优化。
答案 2 :(得分:2)
是。 CASE具有保证的执行顺序,而OR则没有。许多程序员依赖于OR短路,并且惊讶地发现像SQL这样的面向集合的声明性语言并不能保证布尔运算符的短路。
在WHERE子句中使用OR和CASe说是不好的做法。将条件分成清晰的IF语句,并在每个分支上分别进行查询:
IF @col1 IS NOT NULL
SELECT ... WHERE col1 = @col1;
ELSE
SELECT ... WHERE <alternatecondition>;
将条件置于WHERE内部通常会使优化器无法猜测@ col1将会是什么,并产生涉及完整扫描的错误计划。
<强>更新强>
由于我厌倦了一次又一次地解释在SQL中无法保证布尔短路,我决定写一篇关于它的完整博客专栏:SQL Server boolean operator short-circuit。在那里你会发现一个简单的计数器示例,显示布尔短路不仅无法保证,而依赖它实际上可能非常危险,因为它可能导致< strong>运行时错误。