使用PROBE而不是索引搜索进行索引扫描

时间:2014-10-02 15:42:04

标签: sql-server tsql sql-server-2012 sql-execution-plan

我有一个如下所示的查询:

--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

2 个答案:

答案 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列不在索引中。它必须扫描每一行以查看该行是否与您想要的模式匹配。