24

我在 SQL Server 2005 上有一个大小约为 4gb 的表。

(约 1700 万条记录)

我将其中一个字段从数据类型更改char(30)char(60)(总共有 25 个字段,其中大部分是char(10)所以字符空间的数量加起来约为 300)

这导致表的大小加倍(超过 9GB)

然后我将其更改char(60)varchar(60)然后运行一个函数以从数据中删除额外的空格(以便将字段中数据的平均长度减少到大约 15)

这并没有减少表的大小。缩小数据库也无济于事。

除了实际重新创建表结构并复制数据(即 1700 万条记录!)之外,是否有一种不那么激烈的方法可以再次减小大小?

4

5 回答 5

28

即使使用“收缩数据库”,您也没有清理或压缩任何数据。

DBCC 可清理

从表或索引视图中删除的可变长度列中回收空间。

但是,如果有聚集索引,也应该进行简单的索引重建

ALTER INDEX ALL ON dbo.Mytable REBUILD

托尼·罗杰森 (Tony Rogerson) 的一个工作示例

于 2009-04-30T18:22:55.510 回答
20

那么很明显你没有得到任何空间回来!:-)

当您将文本字段更改为 CHAR(60) 时,它们都会被空格填满。因此,您的所有字段现在实际上都是 60 个字符长。

将其改回 VARCHAR(60) 将无济于事 - 这些字段仍然都是 60 个字符长......

您真正需要做的是在所有字段上运行 TRIM 函数以将它们减少回修剪后的长度,然后进行数据库收缩。

完成此操作后,您需要重建聚集索引以回收一些浪费的空间。聚集索引实际上是您的数据所在的位置 - 您可以像这样重建它:

ALTER INDEX IndexName ON YourTable REBUILD 

默认情况下,您的主键是您的聚集索引(除非您另有指定)。

马克

于 2009-04-30T15:57:01.833 回答
3

我知道我没有按照您的要求回答您的问题,但是您是否考虑过将一些数据存档到历史记录表中并使用更少的行?

大多数时候,乍一看,您可能会认为您一直需要所有这些数据,但当您真正坐下来检查它时,有些情况并非如此。或者至少我以前经历过这种情况。

于 2009-04-30T15:53:56.990 回答
0

我在SQL Server 中遇到了类似的问题,将 NTEXT 转换为 NVARCHAR(MAX) ,这与将 ntext 更改为 nvarchar(max) 有关。

我必须做一个UPDATE MyTable SET MyValue = MyValue才能让它很好地调整所有东西的大小。

这显然需要相当长的时间,有很多记录。关于如何更好地做到这一点,有很多建议。他们的关键之一是一个临时标志,指示它是否已完成,然后在循环中一次更新几千个,直到全部完成。这意味着我对它的工作量有“一些”控制权。

但另一方面,如果你真的想尽可能地缩小数据库,如果你将恢复模式降低为简单,缩小事务日志,重新组织页面中的所有数据,然后将其设置回完整状态,它会有所帮助恢复模式。但要小心,通常不建议缩小数据库,如果您减少活动数据库的恢复模型,您就是在要求出现问题。

于 2009-04-30T15:49:09.327 回答
0

或者,您可以进行全表重建,以确保任何地方都没有多余的数据:

CREATE TABLE tmp_table(<column definitions>);
GO
INSERT INTO tmp_table(<columns>) SELECT <columns> FROM <table>;
GO
DROP TABLE <table>;
GO
EXEC sp_rename N'tmp_table', N'<table>';
GO

当然,身份,索引等变得更加复杂......

于 2009-04-30T15:59:35.010 回答