我有一个如下所示的查询:
--Updated To remove Distinct per Aaron Bertrand's suggestion in the comments
SELECT TOP 100 ord.OrderId
FROM Customer cust
JOIN CustomerOrder ord
ON ord.CustomerId = cust.CustomerId
WHERE cust.FirstName LIKE (@firstName + '%')
ORDER BY ord.CreatedWhen DESC
我有一个像这样的索引:
CREATE NONCLUSTERED INDEX [IX_MyIndex] ON CustomerOrder
(
OrderId DESC,
CustomerId DESC,
CreatedWhen Desc
)
GO
当我运行查询时,会使用索引,但它是索引扫描。它给出了这样的信息:
PROBE([Bitmap1011],[MyDatabase]。[order]。[CustomerOrder]。[OrderId] as [ord]。[OrderId],N'[IN ROW]')
输出列表由OrderId和CreatedWhen组成。
PROBE在做什么以及为什么我没有获得索引寻求?
更新:
Customer表上的FirstName列确实有一个在IndexSeek中使用的索引。
CREATE NONCLUSTERED INDEX [IX_Customer_FirstName] ON Customer
(
[FirstName] ASC
)
GO
答案 0 :(得分:1)
使用索引扫描的原因是因为您的WHERE子句谓词基于CustomerId,但在非聚集索引[IX_MyIndex]的列列表中,它显示为 SECOND 列。
如果要执行索引搜索,则需要在CustomerId列上指定一个新的非聚集索引。
这实际上是一个好习惯-为OrderId和CustomerId具有两个单独的NC索引。因此,当您联接Customer和CustomerOrder表时,它将使用NC索引作为CustomerId,当您联接Order和CustomerOrder表时,它将使用NC索引作为OrderId。
请参阅此article,以详细了解多列非聚集索引(您当前拥有)和多个非聚集索引(我建议使用)之间的区别。
[UPDATE]
但是创建单独的非聚集索引不足以每次都获得索引查找。这将取决于查询中选择的列以及要读取的数据的大小-基于此,查询优化器将相应地决定是使用索引查找还是索引扫描。有关更多信息,请参见this answer。
答案 1 :(得分:0)
简单原因:您的FirstName
列不在索引中。它必须扫描每一行以查看该行是否与您想要的模式匹配。