聚集索引 - 查询执行索引扫描

K09*_*K09 3 sql-server index-tuning

为什么下面的查询执行索引扫描而不是索引查找?

我会认为索引会充当覆盖索引吗?

CREATE NONCLUSTERED INDEX [IX_CustomerFileDate] 
ON [dbo].[UserData] 
(
    [CustomerID] ASC,
    [FileDate] ASC
)
INCLUDE ([UserID],[User])

-- query
SELECT c.User, c.UserID 
FROM ClientData c
WHERE CustomerID = @CustomerID
AND FileDate >= @StartDate
AND FileDate <= @EndDate
Run Code Online (Sandbox Code Playgroud)

执行计划发布到Dropbox

谢谢!

Edw*_*and 7

执行计划显示非聚集索引扫描:

在此处输入图片说明

因为您对第一个索引查找列进行了隐式转换,所以 SQL Server 决定执行完整的非聚集索引扫描。它没有进行聚集索引扫描,因为非聚集索引是覆盖索引。1)

在此处输入图片说明

您可以看到列 customerID 需要转换为 NVARCHAR(50) 数据类型。(红色转换)。因为列首先需要转换,所以不能使用。由于它是索引中的第一列,因此它有效地使索引无法用于查找或估计。

为什么 SQL Server 对列进行隐式转换?因为在 = 符号的右侧,你给它一个 Nvarchar。你没有这样做,因为参数 @CustomerID 首先被隐式转换为 NVARCHAR(3) (蓝色转换)。

我认为这是因为您正在使用 Unicode 值填充 @CustomerID。但是,如果您使用 unicode 值并且在您的表中定义了非 unicode 数据类型,这会让我感到惊讶。也许其他人可以确认蓝色转换的原因。

1)我删除了一个关于返回行数相关性的错误假设,Martin Smith很好地向我指出了这个假设。