使用 DELETE 语句从表中删除数据后,表使用的空间不会完全释放SQL Server

本文可帮助你解决使用 DELETE 语句从表中删除所有数据后无法释放表使用的问题。

原始产品版本:SQL Server
原始 KB 编号: 913399

症状

在 Microsoft SQL Server 中使用 DELETE 语句从表中删除数据后,你可能会注意到该表使用的空间未完全释放。 尝试在数据库中插入数据时,可能会收到以下错误消息:

无法为数据库“DatabaseName”中的对象“TableName”分配空间,因为“PRIMARY”文件组已满。

注意

TableName 表示表的名称。 DatabaseName 表示包含表的数据库的名称。

原因

出现此问题的原因是,SQL Server仅在满足以下条件时释放堆表使用的所有页面:

  • 删除此表。
  • 正在保留表级锁。

注意

堆表是未与聚集索引关联的任何表。

如果未解除分配页,则数据库中的其他对象无法重复使用这些页。

但是,在 SQL Server 数据库中启用行versioning-based隔离级别时,即使持有表级锁,也无法释放页。 有关行versioning-based隔离级别的详细信息,请参阅 SQL Server 数据库引擎中的隔离级别

解决方法

若要解决此问题,请使用以下方法之一:

  • 如果未启用基于行版本的隔离级别,请在 DELETE 语句中包含 TABLOCK 提示。 例如,使用类似于以下内容的 语句:

    DELETE FROM <TableName> WITH (TABLOCK)
    

    注意

    <TableName> 表示表的名称。

  • 如果要删除表中的所有记录,请使用 TRUNCATE TABLE 语句。 例如,使用类似于以下内容的 语句:

    TRUNCATE TABLE <TableName>
    
  • 在表的列上创建聚集索引。 有关如何在表上创建聚集索引的详细信息,请参阅 创建聚集索引