1

Sales.SalesOrderDetail数据库中有一个表AdventureWorks2014

我有两个疑问:

--Query 1 uses index IX_SalesOrderDetail_ProductID
SELECT
sod.SalesOrderID
FROM Sales.SalesOrderDetail sod
WHERE sod.SalesOrderID = 1

和:

--Query 2 uses index PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID
SELECT
sod.SalesOrderID
FROM Sales.SalesOrderDetail sod
WHERE sod.SalesOrderID > 1

查询计划: 在此处输入图像描述

可以在此处查看 Brentozar.com 上的查询计划。

和索引:

CREATE NONCLUSTERED INDEX [IX_SalesOrderDetail_ProductID] ON [Sales]. 
[SalesOrderDetail]
(
    [ProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, 
    DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, 
    ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

和聚集索引看起来像这样:

ALTER TABLE [Sales].[SalesOrderDetail] ADD  CONSTRAINT 
[PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID] PRIMARY KEY CLUSTERED 
(
    [SalesOrderID] ASC,
    [SalesOrderDetailID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, 
IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, 
    ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

我的问题是为什么查询优化器更喜欢另一个索引 PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID 而不是IX_SalesOrderDetail_ProductID

4

1 回答 1

3

好吧,我的意思是,您正在选择所有行(可能只有一个行除外)。这里的搜索和扫描之间真的没有区别。SQL Server 选择对最窄的索引执行单次扫描,而不是执行 80,000 次查找(或者无论表中有多少订单)。

搜索并不总是最好的选择,但这是一个常见的误解。事实上,有时你绝对想要扫描。

于 2018-11-03T21:30:35.110 回答