2010-06-24 81 views
9

什么是在SQL查询中检查列的空值或值的有效方法。考虑具有索引的整数列column的sql表table@value可以是一些整数或空例如:16或null。用于比较SQL中列的NULL或值的有效方法

查询1:不确定,但似乎不应该依赖SQL中的短路。但是,当@value是某个整数或null时,下面的查询总是可以正常工作。

select * from 
table 
where (@value is null or column = @value) 

以下查询是上述查询的扩展版本。它也可以正常工作。

select * from 
table 
where ((@value is null) 
    or (@value is not null and column = @value)) 

上述2个查询会利用索引吗?

查询2:下面的查询比较列与非空@value否则将列column与它自己进行比较,它总是为真并返回所有内容。它也可以正常工作。这个查询会利用索引吗?

select * from 
table 
where (column = isnull(@value, column)) 

什么是最好的方法?

注意:如果答案因数据库而异,我对MS-SQL感兴趣。

+4

,以确定是否会有些使用索引或不就是最好的方法创建一个包含大量行的测试表,创建索引并检查查询的查询计划。 – 2010-06-24 14:42:45

+1

请注意,由于条件null = null的计算结果为null,因此Query 2 **不会返回表中列值为null的值,而不是true。 – 2010-06-24 14:53:41

+0

马克,谢谢指出。该列不为空,因此在这种情况下不会发生。 – hIpPy 2010-06-24 15:10:23

回答

1

在过去的几天里,这个问题的变化出现了几次(为什么这些事情总是发生在团队中?)。简短的回答是,如果SQL Server将创建具有已知值的查询计划,它将使逻辑短路。所以,如果你在代码中设置了变量的脚本,那么我相信它应该将逻辑短路(测试是肯定的)。但是,如果它在存储过程中,那么SQL Server将提前创建一个查询计划,并且它不会知道它是否可以使查询短路,因为它在生成时不知道参数值查询计划。

无论是否短路,SQL Server应该能够使用索引,如果这是您的查询的唯一部分。如果变量为NULL,那么你可能不希望SQL Server使用索引,因为它将是无用的。

如果你在存储过程中,那么你最好的选择是在你的查询中使用OPTION(RECOMPILE)。这将导致SQL Server每次都创建一个新的查询计划。这是一点点的开销,但是收益通常超过了很多。这仅适用于SQL 2008,即使只适用于以后的某些Service Pack。之前,RECOMPILE存在一个错误,使其无法使用。欲了解更多信息,请查阅Erland Sommarskog的主题great article。具体来说,您需要查看静态SQL部分。

1

为了澄清一点,SQL并没有像我们在C语言中所知道的那样确实存在短路。什么看起来像一个短路真的是SQL Server三元逻辑TRUE或NULL值为TRUE

TRUE OR NULL ===> TRUE 
TRUE AND NULL ===> NULL 

如:

if 1=null or 1=1 print 'true' else print 'false' 
if 1=null and 1=1 print 'true' else print 'false'