我大约有300张 table ,每张 table 有5.5kk行。其中一行使用nvarchar(128)作为数据类型(SQL Server 2012)。
我们决定将其更改为int,并使用所有nvarchars将FK添加到字典表中。

完成所有操作后,我删除了nvarchar列,但是表的大小保持不变。
我使用DBCC CLEANTABLE并重建了索引以回收可用空间,但是表的大小仍然没有改变。

到目前为止,我发现的唯一方法是将所有数据复制到新表中。

问题:我在这里想念什么?为什么通过缩小或CREANTABLE命令仍将空间标记为已使用,而我却无法释放空间?

谢谢!

回答:答案很简单,由于缺乏知识,我无法找到答案。
这里的主要问题是堆碎片。这个查询对我有用:

ALTER TABLE [TABLE_NAME] REBUILD

我不确定这是否是最好的方法,但至少这是可行的方法。

编辑1 :
抱歉,我想忘记提及-我在Text字段上聚集了索引,因此我必须删除索引才能真正删除该字段。现在我没有索引。

编辑2 :

旧表:
CREATE TABLE [dbo].[Data_](
    [ID] [bigint] PRIMARY KEY IDENTITY(1,1) NOT NULL,
    [Text] [nvarchar](128) NOT NULL,
    [Category] [tinyint] NOT NULL,
    [Country] [nvarchar](2) NOT NULL,
    [ImportTimestamp] [date] NOT NULL
)

新表:
CREATE TABLE [dbo].[Data_New](
    [ID] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
    [Category] [tinyint] NOT NULL,
    [Country] [nvarchar](2) NOT NULL,
    [TextID] [int] NOT NULL)

ALTER TABLE [dbo].[Data_New]  WITH CHECK ADD FOREIGN KEY([TextID])
REFERENCES [dbo].[Dictionary] ([Id])

复制脚本:
INSERT INTO Data_New
      ([Category]
      ,[Country]
      ,[TextID])
SELECT
      [Category]
      ,[Country]
      ,[TextID]
  FROM Data_

最佳答案

如果您不关心了解问题,而只是想摆脱它,那么重建索引是消除浪费的一种可靠方法。这是因为索引重建会重新构建物理数据结构。包含的旧索引将不再重要。

CLEANTABLE进行比较时,需要权衡取舍。如果重建为您完成了工作,那么我将始终这样做,因为它是一个如此完善的解决方案。

当我在此答案中说“索引”时,是指包含您关心的列之一的所有物理结构。可以是b树索引或表所基于的堆。

关于sql - DBCC CLEANTABLE不会释放已用空间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36421826/

10-15 23:43