2012-02-17 115 views
2

以下兩個查詢中,哪一個更快?該表包含超過100M條記錄。所以我只想知道在where子句中使用ISNULL是否與首先爲變量賦值並僅在where子句中使用變量相同?日期範圍查詢方法的性能比較

declare @dt datetime 
select COUNT(*) from pandl 
    where PaymentDate >= ISNULL(@dt, convert(nvarchar(10),getdate(), 121)) 

select @dt = ISNULL(@dt, convert(nvarchar(10),getdate(), 121)) 
select COUNT(*) from pandl 
    where PaymentDate >= @dt 
+7

你是否運行它們以查看哪個更快?您是否使用過SQL Profiler來查看每個查詢的執行計劃? – Pondlife 2012-02-17 13:54:28

+0

你想使用多少個不同的「現在」值?第二個查詢捕獲當前的日期/時間,如果需要的話,然後搜索。 – HABO 2012-02-17 14:04:31

+1

@ user92546這是一個很好的觀點,但僅僅爲了添加一些信息,即使'getdate()'在第一個查詢過程中被多次評估(我將不得不運行一些測試來驗證),因爲轉換將它舍入了它直到今天,如果查詢在午夜之前開始並且仍然在處理(並且在午夜之後將新值賦給'getdate()'),那才真正重要。我完全同意你的看法,一次分配更好,只是想澄清什麼時候它可能非常糟糕,而不是「最好」。 – 2012-02-17 14:18:26

回答

2

第二個會更好。從where子句中調用函數將使查詢優化器使用掃描而不是搜索。換句話說,你會得到一個不太理想的執行計劃

+0

+1 Hola Brandon! – 2012-02-17 14:02:00

+2

從'where'子句檢查的值*上調用函數*肯定會導致掃描。但是我的印象是,如果返回值在調用的整個過程中不會改變,SQL Server就足夠了解調用該函數的次數。 – cHao 2012-02-17 14:06:58

+0

@ cHao是的,這是真的,問題中的兩個版本都不會導致掃描。我只是給了布蘭登第一個+1,因爲我同意他的第一句話。 :-) – 2012-02-17 14:09:45

2

我會建議一個稍微不同的方法,避免稍微昂貴的轉換爲字符串,並使用稍小的數據類型來存儲日期(因爲你不喜歡「T需要分分鐘的間隔,如果你只在乎時間的界限):

DECLARE @dt SMALLDATETIME; 
SET @dt = DATEADD(DAY, DATEDIFF(DAY, '19000101', CURRENT_TIMESTAMP), '19000101'); --* 

SELECT COUNT(*) FROM dbo.pandl 
    WHERE PaymentDate >= @dt; 

如果你想繼續使用轉換爲字符串,使用CHAR(10) - 我不認爲風格121將生成需要Unicode支持的任何日期格式。

*是的,你可以做到這一點沒有外DATEADD但與新的類型,如DATE

1

FWIW,如果你沒有一個指標,它是不會影響計劃:在文本模式下

http://data.stackexchange.com/stackoverflow/query/61684/http-stackoverflow-com-questions-9329461-ms-sql-query-performance

運行,檢查顯示的執行計劃。

我想在StackExchange這些日期列之一將有一個索引,但我沒有找到一個。

除此之外,我在這方面的其他答案 - 不要不必要地使用nvarchar,不要將日期轉換爲字符串沒有很好的理由,不要使用可以在查詢之外更易讀的函數在查詢內部(如果不需要,請不要在查詢中使用函數)。

+0

+1顯示實際執行計劃! – Justin 2012-02-17 14:20:26