什么阻止MS SQL Server数据库收缩?

我有一个9 GB的MS SQL Server 2000数据库,其中有大约1 GB的实际数据。 它在一个共享的Web主机上。 我需要减小尺寸以避免支付极端主机费用。

我曾尝试使用DBCC SHRINKDATABASEDBCC SHRINKFILE 。 他们都不缩小数据库。 ( 是的,我知道我不应该使用它们。 )

DBCC SHRINKDATABASE(db_name)返回:

  DbId FIleId CurrentSize MinimumSize UsedPages EstimatedPages
 23 1 1114808 128 1113824 1113824
 23 2 63 63 56 56 

DBCC SHRINKFILE(1)返回:

  DbId FIleId CurrentSize MinimumSize UsedPages EstimatedPages
 23 1 1114808 128 1113824 1113824 

在常规属性页面中,大小被列为8,709 MB。 可用空间被列为0 MB。 在文件属性页面中,主文件列出,初始大小为8,652 MB。

DBCC SHOWCONTIG(bigTable)返回:

  - 扫描页数................................:807
 - 扫描范围..............................:103
 - 扩展开关..............................:102
 - 平均 每个页面的页数........................:7.8
 - 扫描密度[最佳计数:实际计数] .......:98.06%[101:103]
 - 逻辑扫描碎片..................:0.37%
 - 范围扫描碎片....................:1.94%
 - 平均 每页免费字节数.................................... 68.5
 - 平均 页面密度(全部)..................... 99.15% 

运行sp_spaceused ,我得到这个:

数据库大小:9131.94 MB
未分配的空间:377.95 MB

运行sp_spaceusused bigTable ,我得到这个:

行数:56,095
保留:6,419,736 KB
数据:252,656 KB
Index_size:4,640 KB
未使用:6,162,440 KB

运行sp_spaceusused bigTable2 ,我得到这个:

行数:2,791
保留:2,362,744 KB
数据:114,232 KB
Index_size:200 KB
未使用:2,248,312 KB

其余的桌子都很小。

我问我的主机备份数据库,删除并重新创build一个较小的初始大小,然后恢复它。 他们试了一下,这就是他们的回答:“我们按照步骤进行了,但是没有解决问题,顺便说一句,SQL服务器已经扩大了数据库的大小,目前的大小超过了9GB。” (他们尝试这个之前是7GB)

有没有可能我的数据库需要8GB的未使用空间? 假设它没有,我还有什么其他的select来缩小它?


我能够从我的networking主机上下载一个副本在我的本地计算机上工作。 我安装了SQL Server 2008的试用版并附加了数据库。 我已经运行了ALTER INDEX ALL BIGTABLE REORGANIZE,ALTER INDEX ALL BIGTABLE REBUILD和DBCC SHRINKDATABASE。 什么也没有变。 我仍然从上面列出的各种命令得到相同的基本回应。

这个数据库的恢复模式是什么? 在运行DBCC_SHRINKDATABASE之前,您必须备份您的事务日志。 我猜测恢复模式是完整的? 这在大多数情况下可能是最好的。

这个数据库的数据库备份有多频繁? 什么时候是最后一次运行事务日志备份。

你也可以试试DBCC SHRINKDATABASE(DatabaseName,TRUNCATEONLY);

当你让他们删除数据库,重新创build一个较小的大小,并恢复数据库应该没有改变。 在还原数据库时,SQL Server所做的第一件事是删除当前存在的数据库。

使用DBCC SHRINKFILE命令是正确的方法。 你只需要获得SQL来让你移动一些数据。

您可能需要重build表上的索引以压缩数据页,以便SQL Server从表中删除一些可用空间。 当您使用DBCC SHRINKFILE来缩小物理文件时,它将围绕文件内的数据页面移动,以便所有空白页面位于文件末尾,然后释放数据页面。 但是,如果你的页面只是部分满了,那么当使用这个命令时,SQL Server不会把它们组合起来。

这可以通过使用reindex命令来完成(实际的命令根据使用的SQL Server的版本而有所不同)。 这将压缩一些logging(取决于创build表/索引时指定的填充因子级别)。

您还应该知道SQL Server 2000和更早版本在处理文本和ntext数据types以及在数据页面内移动数据时遇到了问题。 这些较旧版本的SQL Server会将数据碎片留在数据文件的周围,因为它们不与任何行关联,所以无法清除。

您的问题最有可能与删除文本或ntext数据没有释放删除的空间 – 这是在所有版本的页面相同。

重build索引的build议是虚假的 – SHOWCONTIG清楚地表明,sp_spaceused清楚地表明浪费的空间不在索引中。 备份日志build议也是假的 – sp_spaceused显示额外的空间在数据文件中,而不是日志。

你有没有在表中的任何文字/ ntext列? 如果是这样,那么在2000年之前和之后获得这个空间的唯一方法就是创build一个新表,然后将数据导出/导入到这个表中。 仅在2005年,我添加了LOB压缩缩小和ALTER INDEX … REORGANIZE。

此外,请注意缩小的两个错误实际上会扩大文本/ ntext数据占用的空间量 – 请确保您位于SP4上。

谢谢

作为一个想法,你可以采取备份,并在本地下载,然后升级到SQL 2008,然后尝试缩小它在自己的机器上? 如果有效,然后将其上传。 放下目前的一个,并用新缩小的replace它。 这也意味着您必须将您的帐户升级到SQL 2008,但至less您可以在本地certificate它是否可行。

大卫,

请你能发表大桌子的定义吗?

一个常见的问题是导致数据types或数据结构的select不当,导致非常大的不可缩放表 这些表可能使用固定大小的数据types来存储可变大小的数据。 例如,如果您将字段定义为char(100),并且许多条目less于完整的100个字符(对于这个问题甚至是NULL),表格仍然需要全部10个字符的存储空间。 在这种情况下,更好的select是varchar(100),它只存储数据,不会不必要地填充数据。 </ignore >

其他一些可能性是您的托pipe服务提供商可能正在使用TRUNCATEONLY或NOTRUNCATE限定符(从而不允许将数据移动到未分配的页面,完全忽略了您的请求的要点),或者他们可能错误地指定了目标百分比(目标百分比是收缩操作后相对于存储的数据的可用空间量)。 在这两种情况下,如果使用GUI来缩小数据库,则可以简单地询问它们发出的SQL命令,或者在发出shrink指令之前查看对话框的屏幕截图。

我希望这有帮助。

杰西卡