条件没有ISNULL臭吗?

Rad*_*ača 5 sql sql-server select isnull

我遇到一篇文章描述了SQL代码可能不正确的不同情况.但是,有一点令我感到惊讶.他们声称

通过使用COALESCE提供默认值,明智地处理可空列中的NULL是明智的

ISNULL也被提到了.他们还参考了这个MSDN网页,给出了一个例子ISNULL.这里的基本思想是使用它更好

SELECT COUNT(*) FROM [dbo].[Table1] WHERE ISNULL([c2],0) > 2;
Run Code Online (Sandbox Code Playgroud)

然后

SELECT COUNT(*) FROM [dbo].[Table1] WHERE [c2] > 2;
Run Code Online (Sandbox Code Playgroud)

但是,第一个变体不是SARG,而结果不受任何影响ISNULL.我理解需要处理NULL使用ISNULLCOALESCE输出,但是,我总是尝试使用IS NULLIS NOT NULL处理NULL谓词.我错过了什么吗?MSDN问题有什么意义?

编辑:为了对讨论做出反应,主要是在这篇文章中,我准备了一个简单的测试

 IF OBJECT_ID('dbo.LogTable', 'U') IS NOT NULL  DROP TABLE dbo.LogTable

 SELECT TOP 100000 DATEADD(day, ( ABS(CHECKSUM(NEWID())) % 65530 ), 0) datesent ,
      CASE WHEN ( ABS(CHECKSUM(NEWID())) % 100 ) = 1 THEN NULL ELSE ( ABS(CHECKSUM(NEWID())) % 1000 ) END ivalue
 INTO [LogTable]
 FROM    sys.sysobjects
 CROSS JOIN sys.all_columns

 CREATE INDEX ix_logtable_ivalue ON LogTable(ivalue asc) INCLUDE(datesent);

 -- Q1
 select * from logtable where isnull(ivalue, 0) > 998

 -- Q2
 select * from logtable where ivalue > 998
Run Code Online (Sandbox Code Playgroud)

但是,ivalue第一季度不是SARG.有没有捕获?如何为此特定数据和查询创建属性SARG?

Mur*_*nik 6

isnull您提供的示例中的检查毫无意义.null > 2返回null,这不是"真",因此无论如何这些行都将从查询中排除.要启动,isnull以这种方式使用将禁止优化器使用索引(c2如果有).

简而言之 - 这听起来像是糟糕的建议.