Sql server 为什么在使用比较运算符时使用索引扫描而不是查找

Sql server 为什么在使用比较运算符时使用索引扫描而不是查找,sql-server,tsql,query-optimization,query-planner,Sql Server,Tsql,Query Optimization,Query Planner,数据库AdventureWorks2014中有一个表Sales.SalesOrderDetail 我有两个问题: --Query 1 uses index IX_SalesOrderDetail_ProductID SELECT sod.SalesOrderID FROM Sales.SalesOrderDetail sod WHERE sod.SalesOrderID = 1 以及: 查询计划: 和索引: CREATE NONCLUSTERED INDEX [IX_SalesOrderD

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

我有两个问题:

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

查询计划:

和索引:

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\u SalesOrderDetail\u SalesOrderID\u SalesOrderDetailID

而不是
IX\u salesforderdetail\u ProductID

好吧,我的意思是,您选择了所有行(可能只有一行除外)。这里搜索和扫描之间真的没有区别。SQL Server选择对最瘦的索引执行一次扫描,而不是执行80000次搜索(或表中的订单数量)

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

  • (见#2)

可能有另一个索引干扰聚集索引。检查索引,禁用任何使用
SalesOrderID
的索引,只需保留聚集索引即可。并尝试更新统计数据。然后再次检查。@iSR5如何才能更新统计信息?将
updatestatistics Sales.SalesOrderDetail与FULLSCAN一起使用实际上您的注释是反向的。第一个查询使用非聚集索引扫描,第二个查询使用聚集索引搜索。请看您所称的“查询1”和“查询2”-您列出它们的顺序,以及代码中的注释。我是否正确地理解了当我想显示表的所有行时,
table scan
table seek
更好地查看整个表?是的,通常seek不适合这样做。SQL Server根据表或索引的行数/%做出决定,请查找“SQL Server中的临界点”。感谢您的回答,有没有办法看出
表扫描
优于
表搜索
?这是索引扫描而不是表扫描。当然,使用FORCESEEK提示并比较I/O和持续时间。为了获得额外的乐趣,添加更多的列,甚至添加索引中未包含的一些列。
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]