与几周前的这个问题密切相关,但答案没有讨论如何做肮脏的行为。情况如下:
我们现在在一个数据库中有 15 GB 的数据,但是应用程序中的一个日志记录错误肆虐并运行了高达 80 GB 的数据,从而为我们提供了大约 130 GB 的数据库文件。我们已经修复了这个错误,清除了受影响的表,我想收回一些空间,也许将数据库降到 40GB 左右。
我想这样做的最大原因是我们可以更轻松地将备份还原到虚拟测试实例上的较小驱动器。
我明白了:收缩是邪恶的,并且会将索引和磁盘文件碎片化。我被卖了。这是一次性事件。
那么怎样才能把痛苦降到最低呢?似乎我应该:
- 用于
DBCC SHRINKFILE (DataFile1, 40000);
瞄准 40 GB。 - 立即使用一些智能重新索引来重新组织和重建索引
- 对物理磁盘进行碎片整理
这会适当地减轻收缩的副作用吗?或者这只会在我申请邪恶联盟的时候结束?
这是我缩小文件的有点手动的方法。十多年来,这对我来说效果很好。
缩小文件不一定是坏事,但这并不意味着它总是最好的做法。
首先,想想你为什么会萎缩。大多数数据库只会变得更大。如果您预计在可预见的将来需要空间,您可能不想缩小。
缩小的最佳理由是您正试图从一些错误中恢复,其中数据文件的大小已经远远超过了不久的将来所需的任何内容。
另一个很好的理由是您需要将受影响的数据库恢复到开发或测试服务器上,这些服务器根本没有存储容量来处理额外的未使用空间。
收缩的最坏原因是您正试图将另一个数据库塞到已经快满的存储上。你会用完空间,接受它是第一步。下一步是制定更多存储(或更少数据库)的计划,而不是抢彼得付钱给保罗。
收缩
tempdb
几乎总是痛苦的。不重启实例很难及时收缩,重启实例是个坏习惯。其次,确保在MDF和NDF文件中留出额外的空间。重新索引将需要一些工作空间。多少钱?这取决于。找到您最大的桌子的大小并将其用作指南。在数据文件中留下这么多空间,我从来没有出错。如果您的文件中没有足够的空间,它们将尝试自动增长。如果 SQL Server 文件中缺少连续空间,您可能会遇到重新索引大表的问题;在重新索引例程运行后,它们似乎永远不会对属性进行碎片整理。
不要使用自动收缩。它适用于在用户工作站上运行的数据库,而不是在专用生产服务器上运行的数据库,并且在很久以前就被认为是出于任何原因使用它现在都不是一个好主意。
使用
dbcc shrinkfile
,不使用dbcc shrinkdatabase
。如果您需要收缩具有多个 * MDF * 的数据库,请以循环方式进行,注意每个文件所属的文件组。为了有效地分散 I/O,SQL Server 需要文件组中大小相等的文件。一般来说,shrinkfile 不会给服务器带来太多负载,但是当我收缩文件时,我会避开高峰需求期,而且我喜欢比平时更仔细地观察性能监视器。
不要试图一次性缩小所有空间。如果您尝试一次性缩小大量空间,则 dbcc 命令通常会显得紧张。磁盘 I/O 将下降,但命令不会完成。
运行 dbcc shrinkfile 后,您将需要重新索引以将数据放回原处。根据您的表格,您可能能够进行在线重新索引,这已被广泛记录。
如果您将文件压缩得太远,文件将尝试自动增长。你不想那样,所以小心不要把东西缩小太多。如有疑问,请留下额外的 GB。
文件级碎片往往发生在具有大量经常增长的数据文件的卷上。频繁删除/重新创建数据库可能会加剧问题。如果您正在缩小文件,它们应该变得更小并且碎片应该更少。没有什么特别的理由认为碎片整理会让事情变得更糟,尽管它会给你的服务器增加 I/O 负载,如果存储已经负载很重,这可能会造成伤害。一些管理员对第三方碎片整理工具发誓,但我只在服务器上使用过微软的工具。同样,我不会在需求高峰期这样做。