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]