在SQL Server执行计划中,索引扫描和索引搜索之间的区别是什么
我在SQL Server 2005上。
答案 0 :(得分:112)
索引扫描是SQL服务器读取整个索引以查找匹配项的位置 - 此时间与索引的大小成正比。
索引搜索是SQL服务器使用索引的b树结构直接寻找匹配记录的地方(请参阅http://mattfleming.com/node/192了解其工作原理) - 所用时间仅与数量成正比匹配记录。
答案 1 :(得分:69)
要遵循的基本规则是扫描很糟糕,Seeks很好。
索引扫描
当SQL Server执行扫描时,它会将要从磁盘读取的对象加载到内存中,然后从上到下读取该对象,查找所需的记录。
索引搜寻
当SQL Server执行搜索时,它知道数据将在索引中的哪个位置,因此它从磁盘加载索引,直接转到它需要的索引部分并读取到数据所在的位置它需要结束。这显然是一种比扫描更有效的操作,因为SQL已经知道它所寻找的数据所在的位置。
如何修改执行计划以使用Seek而不是扫描?
当SQL Server正在查找您的数据时,可能会使SQL Server从搜索切换到扫描的最大问题之一是当您要查找的某些列未包含在您希望它使用的索引中时。大多数情况下,这将使SQL Server回退到执行聚簇索引扫描,因为聚簇索引包含表中的所有列。这是最重要的原因之一(至少在我看来)我们现在能够在索引中包含INCLUDE列,而无需将这些列添加到索引的索引列中。通过在索引中包含其他列,我们可以增加索引的大小,但是我们允许SQL Server读取索引,而不必返回聚簇索引,或者自己获取这些值。
<强>参考强>
有关SQL Server执行计划中每个运算符的详细信息,请参阅....
答案 2 :(得分:13)
索引扫描:
由于扫描触及表中的每一行,无论其是否合格,因此成本与表中的总行数成比例。因此,如果表很小或者大多数行符合谓词的条件,则扫描是一种有效的策略。
索引搜寻:
由于搜索仅触及符合条件的行和包含这些符合条件的行的页面,因此成本与符合条件的行和页面的数量成比例,而不是与表格中的总行数成比例。
索引扫描只是扫描从第一页到最后一页的数据页。 如果表上有索引,并且查询触及大量数据,这意味着查询检索的数据超过50%或90%,然后优化器只扫描所有数据页检索数据行。如果没有索引,那么您可能会在执行计划中看到表扫描(索引扫描)。
对于高度选择性的查询,索引搜索通常是首选。这意味着查询只是请求更少的行或只是检索表中行的其他10个(有些文档说15%)。
通常,查询优化器尝试使用索引查找,这意味着优化器已找到一个有用的索引来检索记录集。但是如果由于表上没有索引或没有有用索引而无法执行此操作,则SQL Server必须扫描满足查询条件的所有记录。
扫描和搜索之间的区别?
扫描返回整个表或索引。搜索基于谓词有效地从索引的一个或多个范围返回行。例如,请考虑以下查询:
select OrderDate from Orders where OrderKey = 2
<强>扫描强>
通过扫描,我们读取orders表中的每一行,评估谓词“WhereKey = 2”,如果谓词为真(即,如果行符合条件),则返回该行。在这种情况下,我们将谓词称为“残差”谓词。为了最大限度地提高性能,我们尽可能评估扫描中的残差谓词。但是,如果谓词太昂贵,我们可以在单独的过滤器迭代器中对其进行评估。残差谓词出现在带有WHERE关键字的文本showplan中或带有标记的XML showplan中。
以下是使用扫描进行此查询的文本showplan(为了简洁而略微编辑):
| -Table Scan(OBJECT:([ORDERS]),WHERE:([ORDERKEY] =(2)))
下图说明了扫描:
由于扫描会触及表中的每一行,无论其是否合格,因此成本与表中的总行数成比例。因此,如果表很小或者大多数行符合谓词的条件,则扫描是一种有效的策略。但是,如果表很大并且大多数行不符合条件,我们会触及更多页面和行,并执行比必要更多的I / O.
<强>求强>
回到这个例子,如果我们在OrderKey上有一个索引,那么搜索可能是一个更好的计划。通过搜索,我们使用索引直接导航到满足谓词的那些行。在这种情况下,我们将谓词称为“搜索”谓词。在大多数情况下,我们不需要将搜索谓词重新评估为残差谓词;索引确保seek只返回符合条件的行。搜索谓词出现在带有SEEK关键字的文本showplan中或带有标记的XML showplan中。
以下是使用搜索的同一查询的文本showplan:
| -Index Seek(OBJECT:([ORDERS]。[OKEY_IDX]),SEEK:([ORDERKEY] =(2))ORDERED FORWARD)
下图说明了搜寻:
由于搜索仅触及符合条件的行和包含这些符合条件的行的页面,因此成本与符合条件的行和页面的数量成比例,而不是与表中的总行数成比例。因此,如果我们具有高度选择性的搜索谓词,则搜索通常是更有效的策略;也就是说,如果我们有一个搜索谓词可以消除表的很大一部分。
关于showplan的说明
在showplan中,我们区分扫描和搜索以及堆上的扫描(没有索引的对象),聚簇索引和非聚簇索引。下表显示了所有有效组合:
https://blogs.msdn.microsoft.com/craigfr/tag/scans-and-seeks/
答案 3 :(得分:6)
简答:
索引扫描:触摸除某些列以外的所有行。
索引搜索:触摸某些行和某些列。
答案 4 :(得分:4)
使用索引扫描,正在扫描索引中的所有行以查找匹配的行。这对小型表来说非常有效。 使用索引搜索,它只需要触摸实际符合标准的行,因此通常更高效
答案 5 :(得分:2)
当索引定义在单行上找不到以满足搜索谓词时,就会发生索引扫描。在这种情况下,SQL Server必须扫描多个页面以查找满足搜索谓词的范围行。
对于索引查找,SQL Server使用索引定义找到与搜索谓词匹配的单行。
Index Seeks更好,更有效。
答案 6 :(得分:0)