2010-03-05 153 views
8

以下查詢對LastModifiedTime列的索引使用索引查找。索引搜索與聚集索引掃描 - 爲什麼選擇掃描?

SELECT 
     CONVERT(varchar, a.ReadTime, 101) as ReadDate, 
     a.SubID, 
     a.PlantID, 
     a.Unit as UnitID, 
     a.SubAssembly 
FROM dbo.Accepts a WITH (NOLOCK) 
WHERE a.LastModifiedTime BETWEEN '3/3/2010' And '3/4/2010' 
AND a.SubAssembly = '400' 

下面的查詢與上述查詢幾乎相同,它使用聚集索引掃描而不是LastModifiedTime上的索引。誰能告訴我爲什麼?而且,更重要的是,我可以做些什麼來讓SQL Server使用LastModifiedTime列上的索引,而不是使用索引提示。

Declare @LastModifiedTimeEnd dateTime 
Declare @LastModifiedTimeStart dateTime 

    SELECT 
      CONVERT(varchar, a.ReadTime, 101) as ReadDate, 
      a.SubID, 
      a.PlantID, 
      a.Unit as UnitID, 
      a.SubAssembly 
    FROM dbo.Accepts a WITH (NOLOCK) 
    WHERE a.LastModifiedTime BETWEEN @LastModifiedTimeStart And @LastModifiedTimeEnd 
    AND a.SubAssembly = '400' 

回答

6

下面的查詢,這幾乎與上述相同的查詢,使用聚簇索引掃描,而不是在LastModifiedTime索引。誰能告訴我爲什麼?

查詢下面建設計劃,並假定一般,聚集索引掃描是更好時,不知道該參數的值。

而且,更重要的是,我可以做些什麼來讓SQL Server使用LastModifiedTime列上的索引,而不使用索引提示。

SELECT 
     CONVERT(varchar, a.ReadTime, 101) as ReadDate, 
     a.SubID, 
     a.PlantID, 
     a.Unit as UnitID, 
     a.SubAssembly 
FROM dbo.Accepts a WITH (NOLOCK) 
WHERE a.LastModifiedTime BETWEEN @LastModifiedTimeStart And @LastModifiedTimeEnd 
AND a.SubAssembly = '400' 
OPTION (OPTIMIZE FOR (@LastModifiedTimeStart = '3/3/2010', @LastModifiedTimeEnd = '3/4/2010')) 

或者,您可以添加OPTION (RECOMPILE),這將創建不同的執行計劃中的每個查詢運行時,取的參數值存入該帳戶(參數嗅探)。

但是,這並不保證索引將被使用。

+0

我很困惑,爲什麼查詢計劃者會假設聚集索引更好。無論參數是什麼,它仍然與具有爲其創建索引的特定列匹配。如果僅用於固定參數,那麼該索引的重點是什麼? – 2010-03-05 19:18:21

+0

@Kent:使用輔助索引檢索一系列值需要將索引連接回表。當範圍較大時,聯合開銷超過排序開銷。 – Quassnoi 2010-03-05 21:06:51

+0

我明白了 - 謝謝。猜測我假設參數嗅探將是默認行爲。假定使用'> = @LastModifiedTimeStart AND <= LastModifiedTimeEnd',如果不指定'OPTION(RECOMPILE)',也會阻止使用非聚集索引。 – 2010-03-06 09:49:43

相關問題