SQL Server堆v.s.聚集索引

时间:2009-08-27 14:13:17

标签: sql-server sql-server-2008 heap clustered-index

我正在使用SQL Server 2008.我知道如果表没有聚簇索引,那么它被称为堆,否则存储模型称为聚簇索引(B-Tree)。

我想更多地了解堆存储的确切含义,它的外观以及它是否被组织为“堆”数据结构(例如最小堆,最大堆)。有推荐的读数吗?我想要更多内部,但不是太深。 : - )

提前谢谢, 乔治

3 个答案:

答案 0 :(得分:38)

堆存储与these heaps无关。

堆只是意味着记录本身没有被排序(即没有彼此链接)。

插入记录时,它只会插入数据库找到的空闲空间。

更新基于堆的表中的行不会影响其他记录(尽管它会影响二级索引)

如果在HEAP表上创建二级索引,RID(一种指向存储空间的物理指针)将用作行指针。

聚簇索引表示记录是B-Tree的一部分。插入记录时,需要重新链接B-Tree

更新群集表中的行会导致重新链接B树,即。即更新其他记录中的内部指针。

如果在聚簇表上创建辅助索引,则聚簇索引键的值将用作行指针。

这意味着聚簇索引应该是唯一的。如果聚簇索引不是唯一的,则会将一个名为uniquifier的特殊隐藏列附加到索引键,使其成为唯一(并且大小更大)。

值得注意的是,在列上创建二级索引会使值或聚簇索引的键成为secondayry索引键的一部分。

通过在集群表上创建索引,实际上总是得到复合索引

CREATE UNIQUE CLUSTERED INDEX CX_mytable_1234 (col1, col2, col3, col4)

CREATE INDEX IX_mytable_5678 (col5, col6, col7, col8)

索引IX_mytable_5678实际上是以下列的索引:

col5
col6
col7
col8
col1
col2
col3
col4

这还有一个副作用:

群集表上的单列索引中的DESC条件在SQL Server

中有意义

这个指数:

CREATE INDEX IX_mytable ON mytable (col1)

可以在这样的查询中使用:

SELECT  TOP 100 *
FROM    mytable
ORDER BY
       col1, id

,而这一个:

CREATE INDEX IX_mytable ON mytable (col1 DESC)

可以在这样的查询中使用:

SELECT  TOP 100 *
FROM    mytable
ORDER BY
       col1, id DESC

答案 1 :(得分:10)

堆只是没有聚类键的表 - 没有强制执行某个物理订单的键。

我不建议在任何时候使用堆 - 除非您临时使用表来批量加载外部文件,然后将这些行分发到其他表。

在所有其他情况下,我强烈建议您使用群集密钥。默认情况下,SQL Server将使用主键作为群集键 - 在大多数情况下,这是一个不错的选择。除非您使用GUID(UNIQUEIDENTIFIER)作为主键,在这种情况下使用它作为您的群集密钥是一个可怕的想法。

请参阅Kimberly Tripp的优秀博客文章GUIDs as Primary and/or the clustering keyThe Clustered Index Debate Continues,以获得优秀的解释,说明为什么您应该始终拥有群集密钥,以及为什么GUID是一个可怕的群集密钥。

我的建议是:

  • 在99%的案例中尝试使用INT IDENTITY作为主键,让SQL Server也使用集群密钥
  • 例外#1:如果您批量加载大量数据,如果没有临时表的主/群集密钥,则可能没问题
  • 例外#2:如果必须使用GUID作为主键,则将聚类键设置为不同的列 - 最好是INT IDENTITY - 我甚至会为此目的创建一个单独的INT列,如果没有其他专栏可以使用

马克

答案 2 :(得分:0)

Books Online是最好的来源!

整个数据库引擎 - 规划和架构 - 表和索引数据结构架构是非常好的内部介绍。

From this link您可以下载本地图书在线版(免费)。这是所有Sql 2008问题的最佳(和官方)参考。