28

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

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

提前谢谢,乔治

4

3 回答 3

39

堆存储与这些堆无关。

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

当您插入一条记录时,它只是被插入到数据库找到的可用空间中。

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

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

聚集索引意味着记录是B-Tree. 插入记录时,B-Tree需要重新链接。

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

如果在聚集表上创建二级索引,则聚集索引键的值用作行指针。

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

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

通过在聚簇表上创建索引,您实际上总是得到一个复合索引

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
于 2009-08-27T14:19:19.750 回答
11

堆只是没有集群键的表——没有强制特定物理顺序的键。

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

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

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

我的建议是:

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

马克

于 2009-08-27T14:34:26.370 回答
0

在线图书是最好的来源!

整个Database Engine - Planning and Architecture - Tables and Index Data Structures Architecture是非常好的内部介绍。

从这个链接您可以下载在线图书的本地副本(它是免费的)。它是对所有 Sql 2008 问题的最佳(和官方)参考。

于 2009-08-27T14:17:58.720 回答