堆(指没有聚集索引的表)

堆是没有聚集索引的表。 可以在存储为堆的表上创建一个或多个非聚集索引。 数据存储在堆中,而无需指定订单。 通常,数据最初以行插入表中的顺序存储,但数据库引擎可以在堆中移动数据,以有效地存储行:因此无法预测数据顺序。 若要确保从堆返回的行的顺序,必须使用 ORDER BY 子句。 若要指定行存储顺序,请在表中创建聚集索引,以便表不是堆。

注释

有时有充分的理由将表保留为堆而非创建聚集索引,但要有效地使用堆是一项高级技能。 大多数表都应具有经过精心选择的聚集索引,除非存在将表保留为堆的良好理由。

何时使用堆

如果表是堆,并且没有任何非聚集索引,则必须检查整个表(表扫描)以查找任何行。 当表格很小时,这可以接受,例如公司 12 个地区办事处的清单。

将表存储为堆时,通过引用由页面上的文件编号、数据页码和槽组成的行标识符(RID)来标识各个行。 行 ID 是一个小型且高效的结构。 有时,当始终通过非聚集索引访问数据并且 RID 小于聚集索引键时,数据架构师会使用堆。

何时不使用堆

当数据经常按排序顺序返回时,请勿使用堆。 在排序列上使用聚集索引可以避免排序操作。

当数据经常组合在一起时,请勿使用堆。 在对数据进行分组之前必须对其进行排序,排序列上的聚集索引可以避免排序操作。

当需要经常从表中查询数据范围时,请勿使用堆结构。 范围列上的聚集索引将避免对整个堆进行排序。

当表很大且没有非聚集索引时,不要使用堆。 在堆中,必须读取堆的所有行才能查找任何行。

管理堆

若要创建堆,请创建不包含聚集索引的表。 如果表已有聚集索引,则应删除聚集索引以将表返回到堆。

若要删除堆,请在堆上创建聚集索引。

若要重新生成堆以回收浪费的空间,请在堆上创建聚集索引,然后删除该聚集索引。

警告

创建或删除聚集索引需要重写整个表。 如果表具有非聚集索引,则必须在更改聚集索引时重新创建所有非聚集索引。 因此,从堆更改为聚集索引结构或返回可能需要很长时间,并且需要磁盘空间才能在 tempdb 中重新排序数据。

创建索引(Transact-SQL)

DROP INDEX (Transact-SQL)

描述的聚集索引和非聚集索引