我们有一个总大小为 3886 GB 的数据库。其中 778 GB 是免费的。因此,总共存在 3108 GB 的数据。
其中 2458 GB 是“LOB 数据”,400 GB 是“常规”。
由于数据库托管在 AWS 上,因此为了节省成本,我们正在尝试缩小数据文件以释放空间。儿子为了容纳数据,我们已经有两个 2 TB 的驱动器,而且都快满了,我的经理不想创建另一个驱动器并将新文件放在那里。
但是,当我们尝试一次缩小 2 GB 时,会花费很多时间(看到 dbcc lobcompact 在 sp_who2 中运行),而且我们有时也会看到阻塞。谷歌搜索后,我在下面看到 Paul S. Randal 的博客文章,他还指出 LOB 数据使收缩变慢。
https://www.sqlskills.com/blogs/paul/why-lob-data-makes-shrink-run-slooooowly-t-sql-tuesday-006/
我担心的是:
在这种情况下,有什么办法可以让收缩更快,或者根本没有办法?
当涉及到云时,其他人在这种情况下正在做什么,他们想通过减少存储大小来节省一些成本?
我的理解是正确的,即缩小文件可以以某种方式节省组织成本,还是我在浪费时间并使事情变得更糟?如果是,那我该如何说服他?
收缩数据库并不快。事实上,它往往非常慢,除了减少要压缩的数据之外,您无法加快速度。
收缩是如何工作的?
收缩数据文件时,SQL Server 会从文件末尾取出 8k 页,并将它们移动到文件开头的(随机)位置。它一次将页面移动一页。在某种程度上,数据的逐页移动类似于 a 的
REORGANIZE
工作方式,只是相反。由于页面是单独移动到(随机)新位置的,因此它将通过使先前连续的页面不连续来“打乱”页面,从而产生碎片。逐页移动本质上是缓慢的,这就是为什么
REBUILD
高度碎片化的索引比REORGANIZE
它们更快的原因。REBUILD
反而通常,我建议您只
REBUILD
进入一个新文件组,然后删除或缩小旧(空)文件组。进入REBUILD
新文件组将比缩小更快,因为REBUILD
如果更快REORGANIZE
(并且“向后REORGANIZE
”又名缩小)。然后,在旧文件组为空的情况下,当它为空或几乎为空时,它将快速删除或缩小,因为没有/很少的页面要删除。而且因为收缩会产生碎片,所以无论如何你都需要
REORGANIZE
在收缩之后做一个。LOBing 一个曲线球
在您的方案中,LOB 数据代表 3108GB 总数据中的 2458GB (80%)。当您执行 a
REBUILD
时,它会移动 B-Tree 页面,但不会移动 LOB 数据。所以如果你重建一个新的文件组,你的旧文件组仍然是 60+% 满的。对于具有大量 LOB 数据的表,您需要采用不同的方法。您可以在新文件组中创建一个新表,将数据迁移到该新表,然后交换表名并删除旧表。您可以将此过程视为“手动重建”——除非这样做会允许您将 LOB 数据复制到新文件组。我在一篇关于更改数据类型的博客文章中描述了这种方法,但在这种情况下,完全相同的方法也可以使用——除非您将更改文件组,而不是更改数据类型。
缩小(几乎)空文件组很快
收缩很慢,因为它必须移动分配的页面才能在数据文件的末尾创建连续的可用空间。如果文件组为空,则可以在不移动页面的情况下截断文件末尾,并且会非常快。
如果您要缩小的文件组是,
PRIMARY
那么您将无法将其完全清空——PRIMARY
包含所有系统表和元数据。通过将所有用户表移出PRIMARY
,文件组将几乎是空的,并且需要移动的页面数量非常少。只需移动几页也将非常快,特别是与移动 2TB 的页面相比。