之间有什么区别 clustered 和一个 non-clustered index?

有帮助吗?

解决方案

聚集索引

  • 每桌仅限一张
  • 由于数据按索引顺序物理存储,因此读取速度比非集群更快

非聚集索引

  • 每桌可多次使用
  • 插入和更新操作比聚集索引更快

当选择包含使用索引的字段的数据时,这两种类型的索引都会提高性能,但会减慢更新和插入操作。

由于插入和更新速度较慢,应在通常增量的字段(即 Id 或 Timestamp)上设置聚集索引。

如果索引的选择性高于 95%,SQL Server 通常只会使用索引。

其他提示

聚集索引对磁盘上的数据进行物理排序。这意味着索引不需要额外的数据,但只能有一个聚集索引(显然)。使用聚集索引访问数据是最快的。

所有其他索引必须是非聚集索引。非聚集索引具有来自索引列的数据的副本,这些数据与指向实际数据行的指针保持有序(如果存在则指向聚集索引)。这意味着通过非聚集索引访问数据必须经过额外的间接层。但是,如果您仅选择索引列中可用的数据,则可以直接从重复的索引数据中获取数据(这就是为什么最好只选择您需要的列而不使用 *)

聚集索引物理存储在表上。这意味着它们是最快的,并且每个表只能有一个聚集索引。

非聚集索引是单独存储的,您可以拥有任意数量的索引。

最好的选择是在最常用的唯一列(通常是 PK)上设置聚集索引。您的表中应该始终有一个经过精心挑选的聚集索引,除非出现一个非常令人信服的原因(想不出一个原因,但是嘿,它可能就在那里)不这样做。

聚集索引

  1. 一张表只能有一个聚集索引。
  2. 通常在主键上进行。
  3. 聚集索引的叶节点包含数据页。

非聚集索引

  1. 一张表只能有249个非聚集索引(直到sql 2005版本以后版本最多支持999个非聚集索引)。
  2. 通常在任意键上进行。
  3. 非聚集索引的叶节点不包含数据页。相反,叶节点包含索引行。

聚集索引

  • 一张表中只能有一个聚集索引
  • 对记录进行排序并按照顺序进行物理存储
  • 数据检索比非聚集索引更快
  • 不需要额外的空间来存储逻辑结构

非聚集索引

  • 表中可以有任意数量的非聚集索引
  • 不影响物理顺序。为数据行创建逻辑顺序并使用指向物理数据文件的指针
  • 数据插入/更新比聚集索引更快
  • 使用额外的空间来存储逻辑结构

除了这些差异之外,您还必须知道,当表是非聚集时(当表没有聚集索引时),数据文件是无序的,并且它使用堆数据结构作为数据结构。

集群基本上意味着数据按照表中的物理顺序排列。这就是为什么每桌只能吃一份。

非聚集意味着它“只是”一个逻辑顺序。

优点:

聚集索引非常适合范围(例如select * from my_table 其中 my_key 在 @min 和 @max 之间)

在某些情况下,如果您使用 orderby 语句,DBMS 将不必执行排序工作。

缺点:

聚集索引会减慢插入速度,因为如果新键不按顺序排列,则在放入记录时必须修改记录的物理布局。

聚集索引实际上描述了记录在磁盘上物理存储的顺序,因此只能有一个索引。

非聚集索引定义的逻辑顺序与磁盘上的物理顺序不匹配。

聚集索引本质上是索引列中数据的排序副本。

聚集索引的主要优点是,当您的查询(查找)在索引中定位数据时,不需要额外的 IO 来检索该数据。

维护聚集索引的开销(尤其是在频繁更新的表中)可能会导致性能不佳,因此最好创建非聚集索引。

索引数据库有两部分:一组以任意顺序排列的物理记录,以及一组索引,用于标识应读取记录以产生按某种标准排序的结果的顺序。如果物理排列和索引之间没有相关性,那么按顺序读出所有记录可能需要进行大量独立的单记录读取操作。由于数据库可能能够在比读取两个非连续记录更短的时间内读取数十个连续记录,因此如果索引中连续的记录也连续存储在磁盘上,则性能可能会得到提高。指定索引是聚集的将导致数据库做出一些努力(不同的数据库在多少方面有所不同)来排列事物,以便索引中连续的记录组在磁盘上也是连续的。

例如,如果从一个空的非集群数据库开始并以随机顺序添加 10,000 条记录,则这些记录可能会按照添加顺序添加到末尾。按索引顺序读取数据库需要 10,000 次单记录读取。然而,如果使用集群数据库,系统可能会在添加每条记录时检查前一条记录是否是自己存储的;如果发现情况如此,它可能会将该记录与新记录一起写入数据库末尾。然后,它可以查看移动记录曾经驻留的槽之前的物理记录,并查看其后的记录是否是单独存储的。如果发现情况确实如此,它可以将该记录移至该位置。使用这种方法会导致许多记录成对分组在一起,从而可能使顺序读取速度几乎加倍。

实际上,集群数据库使用比这更复杂的算法。不过,需要注意的一个关键问题是,更新数据库所需的时间和顺序读取数据库所需的时间之间存在权衡。维护集群数据库将显着增加以任何影响排序顺序的方式添加、删除或更新记录所需的工作量。如果数据库的顺序读取频率远高于更新频率,则集群可能是一个巨大的胜利。如果经常更新但很少按顺序读取,则集群可能会造成很大的性能消耗,特别是如果将项目添加到数据库的顺序与其在集群索引方面的排序顺序无关。

// 复制自MSDN,第二点非聚集索引其他答案中没有明确提及。

簇状

  • 群集索引将数据行排序并根据其钥匙值存储在表或视图中。这些是索引定义中包含的列。每个表只能有一个聚类索引,因为数据行本身只能以一个顺序存储。
  • 表中的数据行以排序顺序存储的唯一时间是表包含群集索引时。当表具有群集索引时,该表被称为群集表。如果表没有聚类索引,则其数据行存储在称为堆的无序结构中。

非簇状

  • 非聚集索引具有与数据行分开的结构。非集群索引包含非集群索引键值,并且
    每个键值输入都有一个指向包含键值的数据行的指针。
  • 从非集群索引到数据行的索引行的指针称为行定位器。行定位器的结构取决于数据页是否存储在堆中还是聚类表中。对于堆来说,行定位器是指向行的指针。对于聚类表,行定位器是群集索引键。

您可能已经完成了上述帖子中的理论部分:

-我们可以看到聚集索引直接指向记录,即它是直接的,因此搜索所需的时间更少。此外,它不会占用任何额外的内存/空间来存储索引

- 而在非聚集索引中,它间接指向聚集索引,然后它将访问实际记录,由于其间接性质,它将需要更多时间来访问。而且它需要自己的内存/空间来存储指数

enter image description here

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top