2010-06-25 71 views
17

我在工作中發現了一些查詢和形式等都是使用限制:ISNULL VS是空

isnull(name,'') <> '' 

有什麼特別的原因,爲什麼人們這樣做,而不是更簡潔

name is not null 

這是遺留問題還是性能問題?

+0

如果您準確地引用了代碼,Martin Smith是正確的。如果它實際上是像ISNULL(名稱,「」)<> @name那麼你保持SQL使用任何指標,但你得到的結果更像是甄子丹介紹 – Matt 2010-06-25 13:24:43

+0

@馬特:是的,我在犯了一個錯誤我在例子中給出的代碼。它現在已經修復。 – tgandrews 2010-06-25 13:35:33

回答

30
where isnull(name,'') <> '' 

相當於

where name is not null and name <> '' 

這又相當於

where name <> '' 

(如果名稱IS NULL是最終想要得到未知,行不返回)

使用ISNULL模式將導致掃描並且效率較低可以在下面的測試中看到。

SELECT ca.[name], 
     [number], 
     [type], 
     [low], 
     [high], 
     [status] 
INTO TestTable 
FROM [master].[dbo].[spt_values] 
     CROSS APPLY (SELECT [name] 
        UNION ALL 
        SELECT '' 
        UNION ALL 
        SELECT NULL) ca 


CREATE NONCLUSTERED INDEX IX_TestTable ON dbo.TestTable(name) 

GO 


SELECT name FROM TestTable WHERE isnull(name,'') <> '' 

SELECT name FROM TestTable WHERE name is not null and name <> '' 
/*Can be simplified to just WHERE name <> '' */ 

哪應該給你你需要的執行計劃。

enter image description here

+0

「使用這種圖案的...是效率較低的...」的圖案是使用ISNULL或IS NULL ... OR =構造的? – 2015-07-27 18:34:51

+1

@KarlKieninger - 使用'ISNULL'的模式 - 最初有一些執行計劃圖像使得這個更清晰。將重新生成它們.. – 2015-07-27 18:36:49

2

isnull(name,'') <> :name(name is null or name <> :name)的簡寫(假設:name從不包含空字符串,因此爲什麼這樣的shorthands可能很糟糕)。

表現明智,這取決於。在where子句中的or語句可以給出非常差的性能。但是,列上的函數會損害索引使用。像往常一樣:簡介。

+0

'(名稱爲空或''<>:name)'....不是? – 2015-03-24 10:20:23

1
isnull(name,'') <> name 

嗯,我可以看到他們使用這種方式,因爲這種方式如果名稱不匹配或爲空它返回作爲失敗的比較。這實際上意味着:name is nullname <> name

作爲這個name is not null只是檢查名稱是否爲空。

12
is not null 

只會檢查字段是否爲空。如果該字段包含空字符串,則該字段不再爲空。

isnull(name, '') <> name 

檢查空字符串和空字符串。

1

他們並不意味着同樣的事情。

name is not null 

該檢查記錄中,其中名稱字段爲空

isnull(name,'') <> name 

這一個改變了空字段爲空字符串值,使他們能夠在比較中使用。在SQL Server中(但不是在Oracle中我認爲),如果一個值爲null,並且它用於比較等式或不等式,它將不會被認爲是因爲null意味着我不知道該值,因此也不是實際值。所以,如果你想確保做對比時,空的記錄被認爲是,你需要ISNULL或COALESCE(這是ASCII格式條款使用如ISNULL所有數據庫中doen't工作)。

什麼,你應該看到的是

isnull(a.name,'') <> b.name 

a.name <之間的差異性> b.name

那麼你就會明白爲什麼需要ISNULL得到正確的結果。

1

我顯然誤讀了你的問題。因此,讓我打我的第一個答案,試試這個:

isnull(name,'') <> '' 

name is not null and name <> '' 
0

而且誤導快捷鍵,如果你想使用該列的索引,使用

name is not null and name <> '' 
1

其他人指出了功能差異。至於性能問題,在Postgres裏我發現 - 哦,我應該指出,Postgres有一個功能「聚結」,也就是在其他一些SQL方言發現了「ISNULL」相當於 - 但在Postgres的,說

where coalesce(foobar,'')='' 

where foobar is null or foobar='' 

而且顯著更快,它可以赫然顯着快說

where foobar>'' 

where foobar!='' 

大於測試可以使用該索引,從而跳過所有的空白,而不等測試必須執行完整的文件讀取。 (假設你已經在球場上的指標,沒有其他指標優先使用。)

0

這兩個查詢是不一樣的。舉例來說,我沒有一箇中間名,這是一個衆所周知的事實,它可以被存儲爲

MiddleName='' 

但是,如果我們不知道一個人的中間名,我們可以存儲NULL。 所以,ISNULL(MiddleName,'')的意思是「沒有中間名的人」。

0

這是同時處理空字符串和NULL。雖然能夠使用一個語句很好,但isnull是專有語法。我會使用便攜式標準SQL編寫該代碼,如

NULLIF(name, '') IS NOT NULL