收缩SQL Server数据文件,但不是一次全部?

我有一个数据库文件,目前是150GB,但只有75GB正在使用 – 这是因为我把所有的索引(其他75GB)移动到一个新的数据文件。 我想从这个数据文件中至less回收一部分空间,但是当我试图缩小文件时,它会无限期地“执行”,最终会因为networking中断或其他我不能控制的内容而被取消一天运行)。 即使使用“缩小到特定的大小”function,并指定它只是修剪10MB从来没有似乎返回 – 它只是坐直到过程中断。

还有另外一种方法可以回收这个空间,即使是一次一点的收集吗?

编辑:有人张贴链接解释为什么我不应该缩小我的数据库。 我明白了,我想缩小它。 这个服务器上的磁盘空间非常重要,而且数据库在很长一段时间内不会再次扩展到这个未使用的空间中 – 正如我之前所说的,我将索引从数据文件中移出来释放这个空间,所以现在浪费了。

不,使用DBCC SHRINKFILE ('filename', target_size)是正确的方法。

如果你想在“块”中做到这一点,你可以设置逐渐减小的目标尺寸,或者让它在取消之前尽可能长地运行。

几点意见:

  • 提出一个合理的目标大小,并留有一定的空余空间。 可能90GB的总数为75GB的数据?
  • 收缩运行时,请检查活动监视器以查看SPID是否被阻止。 如果在文件最后的页面上有一个打开的事务,那么在事务提交或回退之前,收缩将不能移动它。
  • 蜘蛛实际上是在进步吗? (CPU和IO号码正在改变)
  • 收缩有时可能需要很长时间,但是应该保存它的进度 (意味着它每次移动1页,当它被取消时,所有完成的页面移动已经完成)
  • 取消收缩后,尝试执行DBCC SHRINKFILE ('filename', TRUNCATEONLY) 。 它应该恢复文件末尾已经释放的所有空间(请参阅我之前的观点)
  • 如果你感到绝望,试试在单用户模式下重新启动SQL,这样你就知道当时没有别的东西在对数据库进行操作了(显然,这在prod服务器上是不可能的)
  • 一旦您能够完成收缩,请确保在数据库上执行完全重新索引以消除收缩创build的碎片。 这可能会回收你刚才释放的一些空间。
  • 如果你仍然不能缩小工作,看看这个SO问题的一些讨论。 显然有一些情况下,缩水可能无法进行。

我们已经在我们的环境中find了几个select:

  1. 如果旧表可以面对,则在全新的文件组上创build新表,并将数据库默认为该表。 加class,删除旧表,直到以前的文件组为空。 然后放下它。
  2. 如果旧表不能面对面,但包含可以脱机几个小时的历史数据,请创build一个指向新文件组的新空表。 交换表并开始复制从旧表到新批的行。 这可能会导致碎片。
  3. 使用EMTPYFILE选项发出DBCC SHRINKFILE选项,数据库将把所有对象移动到新文件中。 然后你可以删除旧文件。 这可能需要很长时间。
  4. 将所有表的聚簇索引(带有DROP_EXISTING的主键)重新创build到新的文件组中。 这将locking表。

祝你好运

如果您不想简单地回收空间(您明确拒绝的空间),但坚持试图缩小数据库,这需要很长时间,而且您的事务日志扩展应该只是覆盖任何空间你从数据库中回收。 作为一个奖励,看看你的数据库performance后通过地板。 如果保罗·兰德尔不能说服你(哪个JL评论过,但我会在这里重新发布: 为什么你不应该缩小你的数据文件 ,缩小是一个可怕的想法,我不确定任何人都可以。 SQL服务器(或至less可以改变,所以它的工作方式像保罗build议)在下一个版本。