2011-06-02 80 views
6

費用不僅在SELECT中使用DateAdd函數,而且在WHERE中使用DateAdd函數。 或者使用最初返回比我需要的更多數據的子查詢,但可以在數據庫上再次使用DateAdd函數的情況下進行過濾。SQL效率 - 使用dateAdd函數查詢兩次;或SubQuery和DateAdd函數一次;在日期之間

執行計劃似乎暗示它們就其而言是相同的。 我想知道哪個會更有效率?

DECLARE @DateFrom DateTime 
    SET @DateFrom = '2011-05-27' 
    DECLARE @DateTo DateTime 
    SET @DateTo = '2011-06-27' 

    SELECT id, name, 
    dateAdd(hour, datediff(hour, getdate(), getutcdate()), --UTC offset 
      dateadd(second, itsm_requiredbyx, '1/1/1970 12:00 AM')) as itsm_requiredbyx 
    FROM tablename 
    WHERE dateAdd(hour, datediff(hour, getdate(), getutcdate()), --UTC offset 
      dateadd(second, itsm_requiredbyx, '1/1/1970 12:00 AM')) 
      BETWEEN @DateFrom AND @DateTo 

    ORDER BY itsm_requiredbyx desc 

    --------------------------------------------------------------------------------------------- 

    SELECT * 
    FROM 
     (
     select id, name, 
     dateAdd(hour, datediff(hour, getdate(), getutcdate()), --UTC offset 
       dateadd(second, itsm_requiredbyx, '1/1/1970 12:00 AM')) as itsm_requiredbyx 
     from tablename 
     ) RR 
    WHERE itsm_requiredbyx BETWEEN @DateFrom AND @DateTo 
    ORDER BY itsm_requiredbyx desc 
+4

我不認爲這很重要。但它看起來是在計算'itsm_requiredbyx'字段,然後檢查結果是否在兩個外部值'@ DateFrom'和'@ DateTo'之間。如果您不對該字段進行任何計算,而是對外部值執行(反向)計算,然後檢查「itsm_requiredbyx」是否在這兩個計算值之間,則查詢可以使用「itsm_requiredbyx」的索引。 – 2011-06-02 09:52:11

+0

語法固定 - 謝謝。 – 2011-06-02 10:02:08

+0

有一些區域設置與UTC的偏移量不是整個小時數。由於您似乎在嘗試編寫國際代碼,因此您可能需要注意這一點。 – 2011-06-02 13:29:53

回答

7

我不認爲這兩個你使用哪個很重要。執行計劃同意。

但似乎你正在計算列itsm_requiredbyx,然後檢查結果是否在兩個外部值@DateFrom@DateTo之間。這樣,在可以應用WHERE條件並且不能使用索引之前,來自該字段的所有日期時間都由函數處理。 @ DOK答案中的第二個鏈接(Ten Common SQL Programming Mistakes)提供了有關發生這種情況的原因和時間的更詳細信息。

如果你不做任何計算的列,但你做的(逆轉)的計算,而不是外部的值,然後檢查是否itsm_requiredbyx這兩個計算值之間,查詢可以使用的指數itsm_requiredbyx(並且函數只會被調用兩次,而不是表中的每一行)。

1

This article可能會幫助您選擇。如果您的日期列被編入索引,則所使用的方法可能會有很大差異,特別是在WHERE子句中。

,因爲它說,

如果你有很多的記錄搜索龐大的表,你將最有可能的索引一些常用於限制查詢的日期列。在WHERE子句中使用日期列時,如果日期列包含在函數中,則查詢優化器不會使用索引。

這也在Ten Common SQL Programming Mistakes在謂詞解釋的那樣,特別是在#上索引列2功能:

的問題的事實, 索引列被傳遞到 一個函數,產生這那麼查詢引擎 必須對錶中的每個單行 進行評估。在諸如 這些情況下,查詢優化程序可以執行的WHERE子句謂詞 被視爲「非SARGable」,最佳的 執行完整索引或表掃描。

爲了確保索引得到使用,我們 需要避免使用索引列上的函數 。