索引搜索与聚簇索引扫描 - 为什么选择扫描?

Ran*_*der 8 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 '3/3/2010' And '3/4/2010'
AND a.SubAssembly = '400'
Run Code Online (Sandbox Code Playgroud)

下面的查询与上述查询几乎完全相同,使用聚簇索引扫描,而不是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'
Run Code Online (Sandbox Code Playgroud)

Qua*_*noi 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'))
Run Code Online (Sandbox Code Playgroud)

或者,您可以添加OPTION (RECOMPILE),每次运行查询时都会创建不同的执行计划,将参数值带入帐户(参数嗅探).

但是,这并不能保证将使用索引.


Rem*_*anu 6

您可以使用sp_create_plan_guide创建计划指南.请参阅使用计划指南优化已部署应用程序中的查询.计划指南将帮助优化器决定是使用索引范围搜索还是聚簇扫描.