Rob*_*Rob 5 sql-server compression sql-server-2012
我想知道 SQL Server 是否支持对整个表的一种字典压缩,而不仅仅是一个页面。
我正在开发的系统最初并不是为它今天处理的大量数据而创建的。我目前遇到的问题如下:
该应用程序允许用户创建法律合同。这些合同是标准化的,但允许用户根据需要调整合同的内容(文本)。
为方便起见,每份合同都会制作一份标准化合同文本的副本。实际上,我们发现用户几乎从不编辑合同文本,因此我们最终得到了一个包含大量重复数据的表格。
通常我会更改数据库模型以适应用例,但这是一个遗留系统,这样的更改非常昂贵。正在研究它的替代品,所以像这样的投资并不容易。
是否可以对整个表进行列字典压缩,而不仅仅是 1 页?
我们在内部部署的 SQL 集群中使用 SQL Server 2012。
问题是表大小为 80GB,整个 DB 大小为 180GB。这个表占用了很多空间,我们没有足够的内存,所以 SQL Server 不断卸载数据。
该表的数据用于生成代表合同的 PDF。每次用户修改合同状态时,都会生成一个新的 PDF 并存储用于审计目的,这会在此表上生成大量读取。
读取到磁盘(因为 SQL 服务器不断从内存中卸载表)。这给我们的 SAN 造成了巨大的 IO 压力。
正在解决内存问题,但这需要几周时间。现在可以说,简单地插入更多内存目前不是一种选择。
我的想法是:对于短期解决方案 - 压缩数据,这将大大减少表的大小,从而使 SQL Server 可以将表保存在内存中,从而减轻我们对 SAN 的 IO 压力。
Dav*_*ett 11
是否可以对整个表进行列字典压缩,而不仅仅是 1 页?
对于您描述的 SQL Server 内置压缩的情况,可能根本不会做任何事情。我假设文档存储在NVARCHAR(MAX)列中以允许非 ASCII 字符并允许超过 4,000 个字符的值。任何 SQL Server 方法(行压缩、页面压缩或它们附带的 unicode 压缩)都不会压缩页外值,因此很可能不会触及您的所有文档。
简而言之:没有 SQL Server 可以自动做的任何事情来帮助您。
可能的选项:(有点手动和hacky)
如果您使用的是 2016 或更高版本或 Azure SQL [1][2],那么您可以使用COMPRESS/DECOMPRESS函数将数据存储为 VARBINARY 列中的较小 blob。要以对您的应用程序透明的方式执行此操作,您可以创建一个存储数据的后备表,用从中选择并具有INSTEAD OF触发器来压缩传入数据的视图替换真实表。如果您已经拥有大量数据,这可能需要很长时间才能推出。为了消除对压缩现有内容的数小时维护窗口的需要,在支持表中同时具有NVARCHAR(MAX)和VARBINARY(MAX)列,并让视图决定DocumentText = ISNULL(DECOMPRESS(CompressedText), UncompressedText) 然后你可以让一个进程慢慢地处理表,一次压缩一批行,保持批次足够小以避免锁定问题,这样你就可以让进程在生产中前进。
当然,如果您不仅可以影响数据层,还可以影响应用程序,那么在那里实施文档压缩会更有效,因为您可以节省网络传输以及数据库服务器上的存储和内存。
如果您的许多文档确实完全相同,那么您可能会从重复数据删除中看到比单独压缩每个文档更大的收益,您可以使用类似的技术来做到这一点:将文档存储在它们自己的表中,并将它们的散列作为键/索引并存储在主表中引用它们,使用后备表加视图和触发方法或应用程序数据操作层中的其他地方。在 2016/Azure 中(或者如果使用 CLR 是一个选项),您也可以压缩存储的文档以节省额外的空间。
如果您的许多文档几乎相同,因为它们是从模板构建的,另一种选择是存储模板和差异,尽管这可能需要在应用程序层或通过 CLR 实现,因为我无法想象在其中执行字符串差异和补丁TSQL 在任何地方都足够高效。这仅在文档以未压缩形式(即 RTF 文件、旧办公格式、markdown 文本;而不是最近的 MS Office 格式或 PDF)存储时才有效,因为压缩格式在第一次更改后可能会有所不同。
这些想法增加了复杂性并导致写入性能下降,因此您需要考虑到这些负面因素来判断它们。我自己在类似的情况下使用这些想法,在这种情况下,我们在遗留应用程序中以文本格式收集了大量腌制数据(总共几十 Gb,平均每个项目几千个字符)。当我完成后,我会看看我是否可以获得分享结果的许可。
——
[1] 这个问题后来被更新,以指出在他们的情况下正在使用 SQL2012 - 重复数据删除方法仍然有效,我在答案中留下了压缩方法,因为它可能对其他有类似情况的人有所帮助。事实上,就可以在SQL Server 2012中使用自定义CLR模块来实现压缩,http://aboutsqlserver.com/2015/04/07/compressing-lob-xml-data-in-the-database/是快速搜索的第一个好看的例子,但还有更多。
[2] 正如 Paul 在下面的评论中所指出的,2017 年 LOB 支持将支持压缩列存储索引,因此对于使用足够新版本的 SQL Server 的人来说,这将是另一种研究途径。