为档案进行碎片整理/压缩数据库的最佳方法


9

我们有一个用于电子邮件归档的SQL Server实例(由第三方归档软件包提供)。每隔一段时间,该软件就会被转移到一个新的空数据库中。我们过去每个季度都会做一次,但现在希望每月进行一次。每月要存档的数据量约为15-20 GB,并且大部分数据仅存储在少数几个表中(通常为2-4个)。

一旦我们转到新的数据库,旧数据库就会严格用作只读数据库。我想做的是将其优化为一个美观,紧凑的数据文件,所有表/索引都相邻并且具有很高的填充系数,并且数据文件末尾没有太多的空白空间。另外,我们在此服务器上使用标准版,但存在所有限制(否则,我将已经在使用数据压缩)。

我能想到的几种可能性:

  1. 重建/重新组织索引,DBCC SHRINKFILE(好吧,这不是一个明智的选择,因为DBCC SHRINKFILE会将小便从它接触的任何部分中剔除掉,​​但出于完整性考虑,我将其包括在内。)
  2. 创建一个新数据库并关闭自动统计。编写脚本并从源数据库重新创建所有表。使用bcp以集群键顺序将数据导出/导入到新数据库中。编写脚本并重新创建所有索引。使用全面扫描重新计算所有统计信息。
  3. 创建一个新数据库并关闭自动统计。编写脚本并从源数据库重新创建所有表。使用SSIS或T-SQL将数据传输到新数据库。编写脚本并重新创建所有索引。使用全面扫描重新计算所有统计信息。

在每种情况下,最后一步都是将数据库设置为只读模式。

还有什么其他好的/更好的选择呢?我的担心是以逻辑上连续的方式移动数据,以保留高填充因子。

编辑:

我应该提到,大约75%的数据似乎存储在图像(LOB)列中。


3
您(或应用程序)是否在乎表是否最终位于文件组之外PRIMARY
乔恩·塞格尔

@JonSeigel我不这么认为,实际上,这是一个很好的主意,因为它将为我省去创建模板数据库和移动所有数据的麻烦。
db2

您是只考虑自己编写的解决方案,还是可以查看一些应用程序来帮助自己?您可以使用RedGate的SQL存储压缩来压缩实时数据。或者,您可以尝试虚拟还原以使压缩备份作为联机数据库可用(实际上并没有所需的完整空间)。它们全部基于较旧的Hyperbac Windows文件驱动程序,非常适合压缩实时数据和备份。
玛丽安

@Marian听起来很有趣,但我现在想坚持使用本机SQL Server功能。我只需要非常有效地对数据库进行碎片整理,而文件中不会留有大量未使用的空间。如果它是执行工作而不是手动编写脚本的第三方工具,那很好。
db2

只是一个想法,但是为什么不创建一个新的文件组,添加一个文件,设置一个合理的增长(例如500MB),然后将表重建到该新文件组上。然后将主文件缩小到几乎没有。您无需担心系统表上的碎片。
Nic

Answers:


1

为了消除文件中的物理碎片,您可以将具有拖放功能的聚簇索引移动到新文件组中。由于它们将成为RO,因此将它们的填充系数全部设为100%,因为不需要插入空间,更新导致的页面拆分。

如果您决定转至企业版,这还可以使您执行零碎的还原并使数据库快速联机。Enterprise还允许使用列存储索引,从而大大减少了此只读数据的查询时间,而后者是一个巨大的圆角。

在切换为只读之前,可以使用一次rinklefile选项,而不会出现任何严重的碎片问题,可以根据需要删除文件末尾的空间。

附带一提,只需检查您是否正在为LOBS使用最新的数据类型。即nvarchar(max)或varchar(max)代替ntext或text,varbinary(max)代替image?


不幸的是,它主要使用文本和图像。这是第三方应用程序,所以我没有能力进行更改。
db2

@对于应用程序来说是真正透明的,如果<8k,则SQL Server将信息存储在行中。如果供应商说它不受支持,我会问他们为什么他们仍然使用最初在SQL Server 2005中不推荐使用的数据类型!
损坏的货物2013年

我不能完全确定该应用程序不会执行特定于文本/图像的操作,例如WRITETEXT,该操作在更改数据类型后会失败。但是回到重点,看起来重新创建聚簇索引实际上并不会随之移动LOB数据。
db2

您可以执行此操作,但是您必须进入GUI中的设计器,然后展开属性,然后有一个“常规数据空间”,还有一个TEXTIMAGE文件组,更改此设置,但请注意,这会重新创建表!您显然可以为此编写脚本,并在可能的情况下在维护窗口中运行
DamagedGoods 2013年

知道了,这至少是生成适当的重建脚本的有用方法。
db2 2013年

0

使用第三方工具时,我也遇到了类似的问题,该工具也使用图像数据类型来存储非结构化数据,我通过将列转换为使用filestream来解决了该问题。您将需要进行一些测试,以确保该应用程序仍能按预期运行,但是这将使您能够编写自己的归档过程,以高效的方式将数据移至存档数据库。


我怀疑文件流在这种情况下无法很好地扩展。我们在17个数据库中拥有超过1400万行的数据,并且每天以大约15,000的速度获取消息。消息主体的很大一部分低于4 KB,因此NTFS群集浪费可能是残酷的(即使我们添加了块大小小于64KB的新磁盘卷也是如此)。
db2

在那种情况下,您可以将数据类型转换为nvarchar(max)之类的数据,并使用TEXTIMAGE_ON子句为这些大对象指定其他文件组吗?这样一来,您就可以不连续地存储数据,并可以创建自己的流程来管理归档。
Liam Confrey

文件流的使用实际上取决于每个LOBS的大小。我认为每条记录要考虑> 1MB。因此,我同意在这种情况下它不是一种选择
DamagedGoods 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.