【问题标题】:Compressing VARCHAR in SQL 2008/12 - not seeing results在 SQL 2008/12 中压缩 VARCHAR - 看不到结果
【发布时间】:2012-03-20 16:10:15
【问题描述】:

我一直在尝试在 SQL Server 中进行压缩,但到目前为止我还没有看到预期的结果。

为了测试,我创建了一个包含单个 VARCHAR(8000) 列的新表,并在其中插入了 100k 行。每行包含大约 500 个单词的文本,使用 ZIP 压缩可以节省超过 90% 的空间。

我正在使用命令EXEC sp_estimate_data_compression_savings 'dbo', 'MyTable', NULL, NULL, 'PAGE' ; 来检查使用 PAGE 压缩可以节省多少空间,但它告诉我根本不会有太多空间。结果如下:

object_name schema_name index_id    partition_number    size_with_current_compression_setting(KB)   size_with_requested_compression_setting(KB) sample_size_with_current_compression_setting(KB)    sample_size_with_requested_compression_setting(KB)
MyTable      dbo        0         1                       94048                                                  93440                               40064                                              39808

这基本上没有节省。我哪里错了?

ps。我已经对NVARCHAR(4000) 列进行了相同的实验,并且压缩确实显示了节省,但我相信这是因为压缩强制使用 1 个字符而不是数据不需要 2 个字符的两个字符。它实际上并不像 ZIP 那样压缩数据。

【问题讨论】:

  • 您使用的是页面压缩还是行压缩?桌子上的钥匙是什么?我不知道 500 字是一种很好的压缩模式,因为您不太可能在任何给定页面上获得大量压缩(压缩一次只在单个页面上起作用)。
  • 我测试了 PAGE 和 ROW 压缩。上面的示例中使用了 PAGE。很多话都在重复。如果我压缩一个包含 500 个示例单词的文本文件,则压缩率超过 90%...
  • 但是单个元组中的许多单词重复并不能很好地压缩。 ZIP 的好处是能够跨所有元组进行压缩。
  • @AaronBertrand 对于测试,我使用 int 作为 PK,并且还没有密钥进行了测试。两次结果相似。
  • @AaronBertrand 我不确定我是否跟随。为了澄清,文本在每一行(即在每个 VARCHAR 单元格中)和跨行中都有许多重复的单词。例如,我将小说存储在数据库中,每行存储一个页面。当然,这将是压缩的理想选择。

标签: sql-server sql-server-2008 sql-server-2008-r2


【解决方案1】:

如果数据被推送到行外(这很可能发生在VARCHAR(8000) 列上),那么您不会对其进行任何 压缩。 Only the in-row data is compressed:

由于它们的大小,有时会存储大值数据类型 与特殊用途页面上的普通行数据分开。数据 单独存储的数据不能进行压缩。

【讨论】:

  • 谢谢。我认为你和亚伦是对的。数据可能不在行中,因此根本没有被压缩。这导致了以下问题:a) 我如何检测数据是否在行外,以及 b) 我如何将其保持在行内?我为此创建了一个新问题:stackoverflow.com/questions/9804558/…
【解决方案2】:

SQL Server 中的页面压缩使用前缀和字典方法来压缩数据。它不能(而且您也不希望它)查看整个数据集以找出最佳压缩。它一次只能查看一页数据。当页面中的每个连续行与前一行的差异最小时,可以获得最佳结果。实现此目的的唯一方法是使 SQL Server 物理地排列每一页中的行,以便它们在各行之间的差异尽可能小。我们可以通过在字段或字段集上创建聚集索引来做到这一点,以保证数据行的物理排列遵循行与行模型之间的最小变化。

在您提供的示例中,单个字段中的一堆单词可能无法实现合适的压缩程度。这听起来像是文本段落,并且无论它们的物理排列方式如何,都会有很大的不同。

SQL Server 用于压缩数据的方法使其能够检索任何行的内容,而无需解压缩整个页面。

【讨论】:

  • 对,因为最大键大小为 900 字节,所以无法在示例中显示的列上创建索引。
  • PAGE 压缩包括行压缩。每行中的文本都可以通过其他标准方法(例如 ZIP)进行压缩。我们是说 SQL Server 使用的压缩方法不能压缩包含重复文本的单个 VARCHAR(1234) 单元格吗?
  • 您可以使用大字段的子集创建聚集索引。
  • 这取决于你所说的重复文本的意思。 SQL Server 不会“全力以赴”压缩数据。请记住,它必须能够通过其使用的压缩方法获取和检索单行。如果没有,那么压缩的开销每次都会使服务器瘫痪。 MS 采用了多字段表中大多数类型数据中的模式。
  • 我使用另一种方法来处理压缩文本。我使用 \n Software IPWorks ZIP .net 压缩工具作为 SQL 服务器的 clr。当我需要压缩文本字段时,我将内容提供给 IPWorks zip 控件,并将其存储为 varbinary(max) 字段。
猜你喜欢
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 2010-10-04
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多