I come across an article describing different situation in which the SQL code is probably not correct. However, there is one point which is surprising to me. They claim
it is wise to explicitly handle NULLs in nullable columns, by using COALESCE to provide a default value
ISNULL
is mentioned as well. They also reference this MSDN web page giving an example with ISNULL
. The basic idea here is that it is better to use
SELECT COUNT(*) FROM [dbo].[Table1] WHERE ISNULL([c2],0) > 2;
then
SELECT COUNT(*) FROM [dbo].[Table1] WHERE [c2] > 2;
However, the first variant will not be SARG, whereas, the result is not influenced by ISNULL
at all. I understand the need to handle NULL
using ISNULL
or COALESCE
in the output, however, I always try to use IS NULL
or IS NOT NULL
to handle NULL
in the predicate. Do I miss something? What is the point of the MSDN issue?
EDIT: in order to react on the discussion and mainly on this post I have prepared a simple test
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
However, the ivalue
in Q1 is not SARG. Is there any catch? How should I make the attribute SARG for this particular data and query?