2012-05-19 20 views
2

因爲我們有兩個選擇攔截從數據庫裏的空值...ISNULL與合併正確使用

  1. ISNULL
  2. 凝聚

以下是該方法寫上述兩個函數的查詢...

Select IsNull(Columnname, '') As validColumnValue From TableName

Select Coleasce(Columnname, '') As validColumnValue From TableName

查詢 - 這應該在哪種情況下,爲什麼者優先?

+0

http://www.sqlservercentral.com/Forums/Topic832742-392-1.aspx – Oded

+2

我剛剛寫了這個最近。 http://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/ –

回答

1

開始幽默:第1,第2行不通拼錯了:d END幽默

---整理了迴應---

特點isNull(value1,value2)

  • Only suppo rts 1評估,如果第一個爲空,第二個將被使用,所以如果它的空值太大,你會得到空值!
  • 是非ANSI標準。這意味着如果數據庫可移植性是一個問題,不要使用這一個
  • ISNULL(值1,值2)將返回數據類型值1
  • 將返回數據類型選擇的值,當隱式轉換不會發生
  • 失敗聚結的

特點(值1,值2,值3,值...)

  • 支持多個NULL估值;基本上會拉入列表中的第一個非空值。如果列表中的所有值均爲null,則返回null。
  • 是ANSI標準,意味着數據庫可移植性不應該成爲問題。
  • 將返回所選值的數據類型,如果select中的所有字段都不返回相同的數據類型,則會失敗。

那麼直接回答這個問題: 這要看情況,如果你需要開發的SQL

  • 是DB獨立的;合併使用更加正確。
  • 允許多個評估;合併更準確(當然,你可能只是反覆嵌入...),但把它放在性能顯微鏡下,並且聚結可能會贏。 (我還沒有測試過)
  • 你使用的數據庫引擎支持isNull嗎?(如果不使用聚結)
  • 你想如何處理類型轉換?含蓄或不含。

--- ORIGINAL ------ 爲空只支持2個評估

COALESCE支持更多... COALESCE(columnName1,ColumnName2,ColumnName3, '')

COALESCE返回類似於大小寫評估的數據類型,而isnull返回列表中第一個數據類型。 (我覺得有意思!)

至於什麼時候用哪個。你必須通過查看SQL 2008和2005兩者的執行計劃進行調查,不同版本的不同引擎可以執行不同的方式。

此外,合併是ansii標準,isnull是引擎特定的。因此,如果您希望dbengines之間更好的可移植性,請使用coalesce。

更多信息here aspfaqhere msdn blog

+0

我需要一些時間仔細閱讀您的參考。我會盡快更新並接受它,如果發現有用的話。 – Nilish

+0

在大多數情況下,執行計劃將是相同的。我知道有一個例外:當其中一個表達式是一個子查詢時,它將變成'CASE當'不爲NULL然後 ...'表示子查詢將被評估兩次。希望沒有多少人在說'COALESCE'(,...「 –

+0

」你能詳細解釋一下答案嗎?我其實從來沒有在'Coalesce'中使用'SubQuery'概念。 – Nilish

5

這已被散列和重新散列。除了the tip I pointed out in the comment以及上面發佈的@xQbert鏈接和解釋之外,這裏要求的是使用子查詢對COALESCE與ISNULL的解釋。讓我們考慮這兩個查詢,這在結果方面是相同的:(關於使用TOP時沒有ORDER BY到/ dev/null的/感謝評論)

SELECT COALESCE((SELECT TOP (1) name FROM sys.objects), N'foo'); 

SELECT ISNULL((SELECT TOP (1) name FROM sys.objects), N'foo'); 

在COALESCE情況下,邏輯其實得到擴展到這樣的東西:

SELECT CASE WHEN (SELECT TOP (1) ...) IS NULL 
    THEN (SELECT TOP (1) ...) 
    ELSE N'foo' 
END 

與ISNULL,這不會發生。有一個內部優化似乎確保子查詢只評估一次。我不知道微軟以外的任何人是否確切知道這種優化如何工作,但如果您比較這些計劃,則可以這樣做。下面是COALESCE版本的計劃:

enter image description here

這裏是爲ISNULL版本的計劃 - 注意到它是多麼簡單(即掃描只會發生一次):

enter image description here

在COALESCE情況下,掃描發生兩次。這意味着子查詢會被評估兩次,即使它不會產生任何結果。如果添加WHERE子句以使子查詢產生0行,則會看到類似的差異 - 平面形狀可能會更改,但仍會看到雙重查找+查找或掃描COALESCE情況。這是一個輕微不同的例子:

SELECT COALESCE((SELECT TOP (1) name FROM sys.objects 
    WHERE name = N'no way this exists'), N'foo'); 

SELECT ISNULL((SELECT TOP (1) name FROM sys.objects 
    WHERE name = N'no way this exists'), N'foo'); 

的COALESCE版本這段時間的計劃 - 你可以再次看到整個分支,代表子查詢逐字重複:又一個多

enter image description here

而且簡單的計劃,這樣做大約一半的工作,用ISNULL:

enter image description here

呦ü也可以看到這個問題在上dba.se一些更多的討論:

https://dba.stackexchange.com/questions/4274/performance-difference-for-coalesce-versus-isnull

我的建議是這樣的(你可以看到我的原因,在頂端和上面的問題):信任,但要覈查。我總是使用COALESCE(因爲它是ANSI標準,支持兩個以上的參數,並且不會像數據類型優先級那樣不可靠)除非我知道我使用子查詢作爲表達式之一回想起這樣的理論工作之外)或者我正在經歷一個真正的性能問題,只是想比較一下,看看COALESCE與ISNULL是否有任何實質性的性能差異(除了子查詢的情況下,我還沒有找到)。由於我幾乎總是使用COALESCE來處理類似數據類型的參數,除了回顧我過去所說的內容(我也是7年前的the aspfaq article that xQbert pointed out的作者)之外,我幾乎不必做任何測試。

+0

+1面對它,你就像圍繞coalesce和isnull的討論一樣!但是非常認真,這裏有一些認真深入的東西。 – xQbert

+0

@xQbert有罪:-) –

+0

@AaronBertrand在前2張圖片中,第一個是:(2 * 49.9),第二個是(1 * 99.8)......所以有什麼區別嗎?如果我去100英尺或去50 +50,有什麼關係?請解釋.... :)(即時閱讀執行計劃...) –

0

你可以考慮這一點。

  1. ISNULL功能需要兩個參數:值,以檢查和更換空值

    2. COALESCE功能的工作方式有些不同COALESCE將採取任何數量的參數和返回第一個非NULL值,我更喜歡COALESCE over ISNULL'原因 符合ANSI standarts,而ISNULL沒有。

    我希望你找到了你的問題的答案。