2010-03-05 113 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

相关问题