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
谢谢!
执行计划显示非聚集索引扫描:
因为您对第一个索引查找列进行了隐式转换,所以 SQL Server 决定执行完整的非聚集索引扫描。它没有进行聚集索引扫描,因为非聚集索引是覆盖索引。1)
您可以看到列 customerID 需要转换为 NVARCHAR(50) 数据类型。(红色转换)。因为列首先需要转换,所以不能使用。由于它是索引中的第一列,因此它有效地使索引无法用于查找或估计。
为什么 SQL Server 对列进行隐式转换?因为在 = 符号的右侧,你给它一个 Nvarchar。你没有这样做,因为参数 @CustomerID 首先被隐式转换为 NVARCHAR(3) (蓝色转换)。
我认为这是因为您正在使用 Unicode 值填充 @CustomerID。但是,如果您使用 unicode 值并且在您的表中定义了非 unicode 数据类型,这会让我感到惊讶。也许其他人可以确认蓝色转换的原因。
1)我删除了一个关于返回行数相关性的错误假设,Martin Smith很好地向我指出了这个假设。