2010-08-18 86 views
10

我只是想知道什麼是更快的SQL(特別是SQL Server)。檢查日期是否爲空(NULL)或比較1/0是否更快?

我可以有日期類型的一個空的列和比較,爲NULL,我也可以具有非空的日期列和一個單獨的bit列,bit柱比較1/0

bit列的比較會更快嗎?

+0

我經常想知道這 – TimS 2010-08-18 08:07:26

回答

12

爲了檢查列IS NULL SQL Server實際上只是檢查一下。每行都有一個NULL BITMAP存儲,指示每列是否包含NULL。

+1

會查詢索引的位列在datetime上比null快嗎? – Omu 2011-09-30 08:56:14

+2

@ChuckNorris - 只要實際使用索引,查詢索引就會更快,因爲SQL Server可以直接尋找感興趣的行。如果'datetime'列本身被編入索引,這也是真的。 – 2011-09-30 08:59:54

1

該位將更快,因爲加載到內存的位將只加載1個字節,加載日期將需要8個字節。比較本身將花費同一時間,但從磁盤加載需要更多時間。除非你使用一臺非常舊的服務器或者需要加載多於10^8的行,否則你不會注意到任何事情。

+0

SQL Server將只加載整個8KB頁面進出內存。 – 2010-08-18 11:49:58

2

所有其他的事情都是平等的,我會說比特會更快,因爲它是一個「小」的數據類型。但是,如果性能在這裏非常重要(並且我認爲這是由於該問題),那麼您應該始終進行測試,因爲可能存在其他因素,如索引,影響此的緩存等。

這聽起來像你正在試圖決定一個字段的數據類型,它將記錄事件X是否發生。因此,無論是時間戳(發生X時)或只是一個位(如果X發生,則爲1,否則爲0)。在這種情況下,我會試着去找日期,因爲它會給你提供更多的信息(不僅是X是否發生,而且還有確切的發生時間),這對未來報告的目的最有可能是有用的。如果微小的性能增益真的更重要,只有反對這一點。

2

簡短的回答,如果你只有1和0,像位圖索引1,0是超級快。空值不在某些sqlengines上編入索引,所以'null'和'not null'很慢。但是,在拋棄這個之前,先考慮實體語義。如果你知道我的意思,那麼最好有一個語義表定義。

速度來自在這種情況下使用索引而不是數據大小的能力。

編輯
請參閱Martin Smith的回答。這對於s​​qlserver更有意義,我被Oracle DB帶走了,我的錯誤在這裏。

+2

問題是關於SQL服務器。除非您選擇設置篩選索引以忽略它們,否則SQL Server中的空值會被編入索引。空值在存儲中也用NULL BITMAP表示,所以我不確定會有什麼區別。 – 2010-08-18 11:52:12

9

我只是做了一個簡單的測試:

DECLARE @d DATETIME 
     ,@b BIT = 0 

SELECT 1 
WHERE @d IS NULL 

SELECT 2 
WHERE @b = 0 

實際執行計劃結果表明計算作爲相對於該批次完全相同成本。

Actual Execution Plan

也許有人可以撕裂這一點,但對我來說,似乎沒有任何區別。


多個測試

SET DATEFORMAT ymd; 

CREATE TABLE #datenulltest 
(
    dteDate datetime NULL 
) 

CREATE TABLE #datebittest 
(
    dteDate datetime NOT NULL, 
    bitNull bit DEFAULT (1) 
) 

INSERT INTO #datenulltest (dteDate) 
SELECT CASE WHEN CONVERT(bit, number % 2) = 1 THEN '2010-08-18' ELSE NULL END 
FROM master..spt_values 

INSERT INTO #datebittest (dteDate, bitNull) 
SELECT '2010-08-18', CASE WHEN CONVERT(bit, number % 2) = 1 THEN 0 ELSE 1 END 
FROM master..spt_values 


SELECT 1 
FROM #datenulltest 
WHERE dteDate IS NULL 

SELECT 2 
FROM #datebittest 
WHERE bitNull = CONVERT(bit, 1) 


DROP TABLE #datenulltest 
DROP TABLE #datebittest 

Actual Execution Plan

dteDate IS NULL結果:

IS NULL tooltip

bitNull = 1結果:

bitNull = 1

OK,所以這個擴展的測試出現再次與相同的響應。
我們可以整天這樣做 - 這需要一些非常複雜的查詢來找出平均速度更快的查詢。

+0

查詢優化程序根據幾種策略確定要使用的執行計劃。動態採樣就是其中之一。如果它確定直接表訪問(全表掃描)提取比基於索引的提取有效,則使用它。如果數據量很小,這是非常正確的,但如果數據量很大,則統計數據會有所不同。 – questzen 2010-08-18 09:56:30

+0

@questzen定義巨大的 – Omu 2010-08-18 10:17:51

+1

這是一個難以衡量的問題,但如果我們考慮到兩個場景都會從同一個表中獲取過濾器的數據,那麼大多數計算都會以相同的方式執行。我也可以測試這個,忍受着我。 – Codesleuth 2010-08-18 10:20:01