2017-10-04 39 views
5

我遇到一篇描述SQL代碼可能不正確的不同情況的文章。然而,有一個point這是令我驚訝的。他們聲稱沒有ISNULL臭的條件嗎?

明智的做法是明確的處理在空列空值,通過使用COALESCE提供一個默認值

ISNULL被提及爲好。他們還引用這個MSDN web page舉例ISNULL。這裏的基本想法是,它是更好地使用

SELECT COUNT(*) FROM [dbo].[Table1] WHERE ISNULL([c2],0) > 2; 

然後

SELECT COUNT(*) FROM [dbo].[Table1] WHERE [c2] > 2; 

然而,第一變異不會是特區政府,而,結果不被ISNULL任何影響。我知道需要在輸出中使用ISNULLCOALESCE來處理NULL,但是,我始終嘗試使用IS NULLIS NOT NULL來處理謂詞中的NULL。我想念什麼? MSDN問題的重點是什麼?

編輯:以上討論反應並主要是對本post我已經準備了一個簡單的測試

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 

然而,在Q1的ivalue不SARG。有沒有發現?我應該如何爲這個特定的數據和查詢創建屬性SARG?

+4

你是對的。不要放入不必要的NULL檢查,因爲這會妨礙索引的使用。我強烈推薦'IS NULL' /'IS NOT NULL'。這些是ANSI標準結構。 –

+9

這個例子來自於旨在檢測不良數據庫代碼以進行改進的事實,這一事實非常令人擔憂。你*需要考慮當比較可能爲'NULL'的值時會發生什麼情況,但反思性地將'ISNULL'放在每個地方都是完全錯誤的。 –

+0

'MSDN問題'的一點是什麼?不知道:-)來自[原始來源]的評論(https://www.red-gate.com/simple-talk/sql/t-sql-programming/sql-code-smells/#not-handling-null- values-in-nullable-columns)在計算事物時很有意義,但是[MSDN](https://msdn.microsoft.com/en-us/library/dd172133(v = vs.100).aspx)是完全錯誤的。 –

回答

6

isnull檢查您提供的示例是毫無意義的。 null > 2返回null,這不是「真」,因此這些行將被排除在查詢之外。要啓動,以這種方式使用isnull將禁止優化器使用c2上的索引(如果有的話)。

總之 - 這聽起來像可憐的建議。

+1

「null> 2返回null」 - 不行,此比較返回未知。有點迂腐,但空洞混亂。這一點仍然是正確的 - 沒有理由檢查null。 – SMor

+1

@SMor:非常迂腐,因爲布爾數據類型僅在T-SQL中存在。如果它真的存在(我希望它會非常有用),那麼'UNKNOWN'結果幾乎肯定會由'NULL'表示。不過,我不確定'NULL'如何比'UNKNOWN'更「令人困惑」,因爲這首先是因爲它的存在。 –

+0

'以這種方式使用isnull將禁止優化器使用c2上的索引,如果你有''不完全正確,因爲可能仍然會發布'索引掃描',正如[Pankaj Manek明亮地顯示我們在這裏](http:///www.sqlservercentral.com/blogs/sqlyse-with-pankaj-manek/2015/08/20/isnull-around-the-predicate-and-sargability/)。該聲明適用於'index seek'。 –