SQL Server计划:索引扫描和索引查找的区别

94

在 SQL Server 执行计划中,索引扫描(Index Scan)和索引查找(Index Seek)有什么区别?

我使用的是 SQL Server 2005。

6个回答

143

索引扫描是 SQL 服务器读取整个索引以查找匹配项的过程——这需要的时间与索引大小成比例。

索引搜索是 SQL 服务器使用索引的 B-Tree 结构直接搜索匹配记录的过程(有关其工作原理的想法,请参见http://mattfleming.com/node/192)- 所需时间仅与匹配记录数成比例。

  • 通常情况下,索引搜索优于索引扫描(当匹配记录数量比表中总记录数低得多时),因为执行索引搜索所需的时间是恒定的,无论表中记录的数量如何。
  • 但请注意,在某些情况下,索引扫描可能比索引搜索更快(有时甚至明显更快)-通常是在表很小时或大量记录符合谓词时。

3
链接还有效吗?对我来说无法使用。如果有更新的链接,请帮忙提供帮助。 - Ronak Agrawal
2
@RonakAgrawal 看起来链接确实已经失效了 - 或许可以去 维基百科 上查看? - Justin
7
@RonakAgrawal https://web.archive.org/web/20141003135304/http://www.mattfleming.com:80/node/192 - rebornx

82

遵循的基本规则是扫描(Scans)不好,搜索(Seeks)比较好。

索引扫描(Index Scan)

当SQL Server进行扫描时,它会将要读取的对象从磁盘加载到内存中,然后从上到下遍历该对象,寻找所需的记录。

索引搜索(Index Seek)

当SQL Server进行搜索时,它知道数据在索引中的位置,因此它从磁盘加载索引,直接转到所需的索引部分,并读取所需数据结束的位置。这显然比扫描更有效率,因为SQL已经知道所需数据的位置。


如何修改执行计划以使用搜索而不是扫描?

当SQL Server查找数据时,最可能导致其从搜索切换到扫描的最大因素之一是您要查找的某些列未包含在您想要使用的索引中。大多数情况下,这会导致SQL Server回退到执行聚集索引扫描,因为聚集索引包含表中的所有列。这是我们现在能够在索引中包含列但不将这些列添加到索引列中的原因之一(至少是我的个人意见)。通过在索引中包含附加列,我们增加了索引的大小,但是允许SQL Server读取索引,而无需返回到聚集索引或表本身来获取这些值。

参考资料

有关SQL Server执行计划中每个操作符的具体信息,请参见....


9

简短回答:

  • 索引扫描:访问所有行,但仅涉及某些列。

  • 索引查找:访问特定行和特定列。


如何将索引扫描转换为索引查找。 - Vishe

4

使用索引扫描时,需要扫描索引中的所有行以查找匹配的行。对于小表而言,这可能是有效的。 使用索引查找时,只需操作实际符合条件的行,因此通常更高效。


2

当索引定义无法找到单行以满足搜索谓词时,会发生索引扫描。在这种情况下,SQL Server必须扫描多个页面以查找满足搜索谓词的行范围。

对于索引搜索,SQL Server使用索引定义查找匹配搜索谓词的单个行。

索引搜索更好,更有效。


1

扫描会触及表中的每一行,即使它不是你想要的。

查找只查看你要查找的行。

与扫描相比,查找始终更好,因为它在查找数据时更有效率。

可以在这里找到一个很好的解释。


3
寻找并不总是更好的选择,例如,如果表格相对较小且该表格中有大量的行需要返回,则索引扫描可能会更加高效。 - Justin
1
嗨Justin,我猜你想说有时候全表扫描可能更好。索引搜索总是比索引扫描更好,除非我们在谈论聚集索引。但是,有时候,为了你提到的原因,全表扫描或聚集索引扫描可能更有效率。有时候,即使索引具有条件字段,而不是从表中获取不在索引中的字段,ms sql也会使用表。 - Jose Areas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接