为什么在使用比较运算符时索引扫描而不是查找
Why index scan instead of seek while using comparison operator
数据库 AdventureWorks2014
中有一个 table Sales.SalesOrderDetail
。
我有两个问题:
--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
查询计划:
The query plan at Brentozar.com can be seen here.
和索引:
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
?
嗯,我的意思是,您正在选择 所有 行(可能有一个行除外)。这里的查找和扫描之间确实没有区别。 SQL 服务器选择对最瘦的索引执行单次扫描,而不是进行 80,000 次查找(或者 table 中有很多订单)。
寻求并不总是最好的选择,但这是一个常见的误解。事实上,有时您绝对 想要 扫描。
数据库 AdventureWorks2014
中有一个 table Sales.SalesOrderDetail
。
我有两个问题:
--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
查询计划:
The query plan at Brentozar.com can be seen here.
和索引:
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
?
嗯,我的意思是,您正在选择 所有 行(可能有一个行除外)。这里的查找和扫描之间确实没有区别。 SQL 服务器选择对最瘦的索引执行单次扫描,而不是进行 80,000 次查找(或者 table 中有很多订单)。
寻求并不总是最好的选择,但这是一个常见的误解。事实上,有时您绝对 想要 扫描。