首页 > 解决方案 > RedShift - 为什么不应该压缩 sortykey 列?

问题描述

我知道专家可能会建议这样做,即使我将其作为最佳实践(从 AWS 博客阅读),在Github中有一个非常深入的文档,但我仍然对这个术语感到困惑。It'll affect the range-restricted scan并且无法理解这个概念。

谁能给我一个例子,说明为什么我们不应该在排序键列上使用压缩?

标签: amazon-redshift

解决方案


所以现实是简单的可执行答案通常并不完美,但最好的经验法则。您说您已阅读文档,因此我不会详细说明。此建议背后的假设是排序键也是许多查询中常见的 where 子句。这对于理解建议很重要,但通常是正确的。我有很多关于“where date_col > getdate() - interval '1 year'”的查询,您决定从中创建表“date_col”的排序键——非常典型。

现在,当您运行这种类型的查询时,Redshift 领导节点将根据 date_col 列的块元数据检查 where 条件。无论哪个块中有所需的日期,这些块“匹配”。现在您还要查看其他列的数据。为了获得这些列所需的块,Redshift 为 date_col 列使用了另一条元数据——即每个匹配块中的行号范围。这些行号范围用于根据这些列的元数据查找其他列的块。我希望这是有道理的——找到与 where 子句匹配的块,然后在其他列中找到块。所有这些都不会读取查询不需要的块。

现在举个例子 - 如果你有一个有 2 列的表:1)排序键列是一个 INT 和 2)一个大的 varchar。两者都是压缩的。现在第一列 (INT) 已按排序顺序排列,并将被高度压缩。假设此列适合 1 个块。另一列(大 varchar)占用 10 个块。我们在 INT 列上使用 where 子句运行查询,它匹配 1 块,但与其他列中所需的行号不匹配,从而获得所有 10 个块。没有节省磁盘读取带宽。但是如果 INT 列没有被压缩,它将占用更多的块——比如说 8 个块。相同的查询将仅匹配 INT 列的 8 个块中的一个,并且对 varchar 列的行号交叉引用可能仅匹配该列的 10 个块中的 3 个。现在我们减少了从磁盘读取的数据。

希望这是有道理的。您可以看到,此建议背后有许多假设,这些假设通常是正确的。没有这些假设,很难弄清楚他们为什么这么说。即你的排序键是你常用的 where 子句,sortkey 列的压缩会比其他列好得多,并且 sortkey 中存储的数据比其他列中的数据小。还有一些其他的,但不那么重要。

这有帮助吗?


推荐阅读