请原谅我,但我对成为一名 DBA 还很陌生,因为我最终不得不担任这个角色 :)
我目前正在努力减少几个数据库的大小。我之前在这里问过一个关于如何完成这个的问题,我使用了 DBCC Shrinkfile 命令。它适用于我的第一个数据库,因为文件大小显着减小。但是,当我转到需要减小文件大小的第二个数据库时,DBCC Shrinkfile 查询已经运行了整个周末,但仍未完成。我做错什么了吗?
我之前在这个数据库上测试过 DBCC Shrinkfile 命令,即使只减少 10MB 也需要大约 10 或 20 分钟。我错过了什么吗?有什么我应该事先做的吗?
附加信息:
- 我试图减少的数据库大小为 1.78TB(我将查询设置为将其减少到 1TB),可用空间为 55%。
- 我已将恢复模式设置为简单。
- 链接到我之前的问题
- SQL Server 和 SSMS 2017
- 服务器位于虚拟机上,8 核 cpu Xeon e5,24GB 内存,并在硬盘上运行。
我想强调 JD 在评论中提到的内容,即您只在非常特殊的情况下缩小什么。您已经发现了其中一个原因 - 它可能需要很长时间,几乎到了它似乎不起作用的地步。
两个系统之间的比较部分(但仅部分)与您在其中拥有多少数据有关。考虑将其添加到您的帖子中。不是文件大小,而是其中有多少数据。这是最坏的情况,有多少数据必须从文件末尾移动到文件开头。但即便如此,这也取决于压缩前文件中恰好有可用空间的位置。
不过,我的猜测是该数据库存在以下问题之一:
阻塞,收缩被阻塞的地方。这很容易检查(sp_whoisactive 或您喜欢的任何内容)。
堆表。请记住,对于移动的每个页面,都必须更新该页面上每一行的每个 nc 索引。一个简单的例子,我有一个集群表与堆表相比,堆的收缩时间要长50倍。您可以调查您有多少堆表,并考虑是否应该首先将这些堆表聚集在一起,或者是否可以为收缩过程进行聚集。当然表很大,那么从heap转成clustered就需要很长时间了。
LOB 页面。想象一下 SQL Server 移动一个 lob 页面。它将必须扫描整个表以查看哪些行指向此页,以便它可以修改 LOB 页的页地址。为了。每个。感动。高球。页。让它沉入其中。记住有几种 lob 类型(varbinary(max)、varchar(max)、nvarchar(max)、xml、geography 和 geometry)。这里的选项不多,但是要将 lob 数据导出到不同的文件组,进行压缩然后再返回,或类似的操作。