clustered和non-clustered index之间有什么区别?
clustered
non-clustered index
聚集索引物理地存储在表上。这意味着它们是最快的,并且每个表只能有一个聚集索引。
非聚集索引单独存储,您可以拥有任意数量的索引。
最好的选择是在最常用的唯一列上设置聚集索引,通常是PK。在表中应该始终有一个精心选择的聚集索引,除非有一个非常令人信服的理由——想不出一个,但是,嘿,可能有——不这样做。
聚集索引实际上描述了记录在磁盘上物理存储的顺序,因此只能有一个聚集索引。
非聚集索引定义的逻辑顺序与磁盘上的物理顺序不匹配。
聚集索引
非聚类索引
当选择使用索引的字段的数据时,这两种类型的索引都将提高性能,但会降低更新和插入操作的速度。
由于插入和更新较慢,聚集索引应该设置在一个字段上,通常是增量的,即Id或时间戳。
SQL Server通常只使用选择性高于95%的索引。
聚类基本上意味着数据在表中的物理顺序。这就是为什么每个表只能有一个。
非聚集意味着它“只是”一个逻辑顺序。
聚类索引本质上是索引列中数据的排序副本。
聚集索引的主要优点是,当查询(seek)在索引中定位数据时,不需要额外的IO来检索该数据。
维护聚集索引的开销,特别是在频繁更新的表中,可能会导致性能较差,因此最好创建非聚集索引。
优点:
聚集索引适用于范围(例如:select * from my_table where my_key在@min和@max之间)
在某些情况下,如果使用orderderby语句,DBMS将不需要做排序工作。
缺点:
聚集索引可能会减慢插入速度,因为如果新键不是按顺序排列的,那么在放入记录时必须修改记录的物理布局。
群集索引对磁盘上的数据进行物理排序。这意味着索引不需要额外的数据,但只能有一个聚集索引(显然)。使用聚集索引访问数据是最快的。
所有其他索引必须是非聚集的。非聚集索引具有索引列中数据的副本,并与指向实际数据行的指针(如果存在聚集索引,则指向聚集索引)一起排序。这意味着通过非聚集索引访问数据必须经过额外的间接层。但是,如果您只选择索引列中可用的数据,则可以直接从复制的索引数据中获得数据(这就是为什么只选择您需要的列而不使用*是个好主意)
索引数据库由两部分组成:一组物理记录(按某种任意顺序排列)和一组索引(确定应按何种顺序读取记录以产生按某种标准排序的结果)。如果物理排列和索引之间没有相关性,那么按顺序读取所有记录可能需要执行大量独立的单记录读取操作。由于数据库可能能够在比读取两条非连续记录更短的时间内读取数十条连续记录,因此如果索引中连续的记录也连续地存储在磁盘上,则性能可能会得到提高。指定索引是聚集的将导致数据库做出一些努力(不同的数据库在多大程度上有所不同)来安排内容,以便索引中连续的记录组在磁盘上也是连续的。
例如,如果从一个空的非集群数据库开始,并按随机顺序添加10,000条记录,那么记录可能会在最后按照添加的顺序添加。按索引顺序读取数据库将需要10,000次单记录读取。然而,如果要使用集群数据库,系统可能会在添加每条记录时检查前一条记录是否由自己存储;如果它发现是这样,它可能会在数据库的末尾写入新的记录。然后,它可以查看移动记录所在槽之前的物理记录,并查看后面的记录是否单独存储。如果它发现是这样,它可以将记录移动到那个位置。使用这种方法将导致许多记录成对地组合在一起,因此可能会使顺序读取速度几乎翻倍。
实际上,集群数据库使用比这更复杂的算法。不过,需要注意的一个关键问题是,在更新数据库所需的时间和按顺序读取数据库所需的时间之间存在权衡。维护集群数据库将显著增加以任何可能影响排序顺序的方式添加、删除或更新记录所需的工作量。如果按顺序读取数据库的次数要比更新数据库的次数多得多,那么集群可能是一个巨大的胜利。如果经常更新,但很少按顺序读取,则聚类可能会造成很大的性能消耗,特别是如果将项添加到数据库的顺序与它们与聚类索引的排序顺序无关。
除了这些差异,你必须知道,当表是非聚集的(当表没有聚集索引)数据文件是无序的,它使用堆数据结构作为数据结构。
//复制自MSDN,其他答案中没有明确提到非聚类索引的第二点。
集群
非聚集
你可能已经阅读了以上文章中的理论部分:
-聚类索引,我们可以看到直接指向记录,即它的直接,所以它需要更少的时间进行搜索。此外,它不会占用任何额外的内存/空间来存储索引
而在非聚集索引中,它间接指向聚集索引,然后它将访问实际的记录,由于它的间接性质,它将花费更多的时间来访问。此外,它需要自己的内存/空间来存储索引
非聚簇索引
非聚类索引在检索数据时较慢,在检索数据时较快
一个表可以有多个非聚集索引。
需要额外的空间来存储逻辑结构。
对磁盘上存储数据的顺序没有影响。