gpt4 book ai didi

sql - 表扫描和聚集索引扫描有什么区别?

转载 作者:行者123 更新时间:2023-12-01 17:25:06 25 4
gpt4 key购买 nike

既然表扫描聚集索引扫描本质上都是扫描表中的所有记录,为什么聚集索引扫描据说更好?

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

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

最佳答案

在没有聚集索引的表(堆表)中,数据页不会链接在一起 - 因此遍历页需要 lookup into the Index Allocation Map .

但是,聚簇表的值为 data pages linked in a doubly linked list - 使顺序扫描更快一些。当然,作为交换,您需要在 INSERTUPDATEDELETE 上保持数据页顺序的开销。然而,堆表需要对 IAM 进行第二次写入。

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

当然,聚集索引可以让您执行 CLUSTERED INDEX SEEK,这对于性能来说几乎是最佳的......没有索引的堆总是会导致表扫描。

所以:

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

  • 对于带有 WHERE 子句且可以(至少部分)由聚集索引满足的查询,您将因为排序而领先 - 所以您不会必须扫描整个表格。

  • 对于不满足聚集索引的查询,您几乎是均匀的......再次,唯一的区别是用于顺序扫描的双向链表。无论哪种情况,你都不是最理想的。

  • 对于 INSERTUPDATEDELETE 堆可能会也可能不会获胜。堆不必维持顺序,但需要对 IAM 进行第二次写入。我认为相对性能差异可以忽略不计,但也相当依赖数据。

微软有一个 whitepaper它将聚集索引与堆上的等效非聚集索引进行比较(与我上面讨论的不完全相同,但很接近)。他们的结论基本上是在所有表上放置聚集索引。我将尽力总结他们的结果(再次注意,他们实际上是在此处将非聚集索引与聚集索引进行比较 - 但我认为它是相对可比的):

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

关于sql - 表扫描和聚集索引扫描有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18764/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com