开发者社区> 问答> 正文

表扫描和聚集索引扫描之间有什么区别?

由于a Table Scan和a Clustered Index Scan本质上都扫描了表中的所有记录,因此为什么说“聚集索引扫描”更好?

举个例子-当有很多记录时,以下各项之间的性能差异是什么?:

declare @temp table( SomeColumn varchar(50) )

insert into @temp select 'SomeVal'

select * from @temp


declare @temp table( RowID int not null identity(1,1) primary key, SomeColumn varchar(50) )

insert into @temp select 'SomeVal'

select * from @temp

问题来源于stack overflow

展开
收起
保持可爱mmm 2019-11-15 17:21:10 654 0
1 条回答
写回答
取消 提交回答
  • 在没有聚集索引的表(堆表)中,数据页未链接在一起-因此遍历页需要查找索引分配图。

    但是,一个群集表将其数据页链接在一个双向链接列表中,这使得顺序扫描的速度更快。当然,作为交换,你必须处理保持数据页顺序的开销INSERT,UPDATE和DELETE。但是,堆表需要第二次写入IAM。

    如果您的查询具有RANGE运算符(例如SELECT * FROM TABLE WHERE Id BETWEEN 1 AND 100:),那么聚簇表(按有保证的顺序)将更加高效-因为它可以使用索引页来查找相关的数据页。堆将不得不扫描所有行,因为它不能依赖于排序。

    而且,当然,聚集索引使您可以执行聚集索引SEEK,这对于性能而言是非常理想的……没有索引的堆将始终导致表扫描。

    所以:

    对于选择所有行的示例查询,唯一的区别是聚簇索引维护的双链表。这应该使群集表比具有大量行的堆快一点。

    对于具有WHERE可以(至少部分地)由聚集索引满足的子句的查询,您将因排序而出名-因此您不必扫描整个表。

    同样,对于聚集索引无法满足的查询,您甚至可以...甚至,唯一的区别是用于顺序扫描的双链表。无论哪种情况,您都不理想。

    对于INSERT,UPDATE和DELETE一个堆可能会或可能不会赢。堆不必维护顺序,但是确实需要对IAM进行第二次写入。我认为相对性能差异可以忽略不计,但还取决于数据。

    Microsoft拥有一份白皮书,该白皮书将堆中的聚集索引与等效的非聚集索引进行了比较(与我上面讨论的不完全相同,但是很接近)。他们的结论基本上是在所有表上放置聚簇索引。我将尽力总结他们的结果(再次,请注意,他们实际上是在这里将非聚集索引与聚集索引进行比较-但我认为它是相对可比较的):

    INSERT 性能:由于堆需要进行第二次写入,因此聚集索引的获胜率约为3%。 UPDATE 性能:由于需要对堆进行第二次查找,因此聚集索引的获胜率约为8%。 DELETE 性能:由于需要对IAM进行第二次查找和对堆进行第二次删除,因此聚集索引的获胜率约为18%。 单一SELECT性能:由于需要对堆进行第二次查找,因此聚集索引的获胜率约为16%。 范围SELECT性能:由于对堆的随机排序,聚集索引的获胜率约为29%。 并发INSERT:由于聚集索引的页面拆分,堆表在负载下胜出30%。

    2019-11-15 17:21:23
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
RowKey与索引设计:技巧与案例分析 立即下载
Phoenix 全局索引原理与实践 立即下载
事务、全局索引、透明分布式 立即下载