【问题标题】:Redshift doesn't recognize newly loaded data as pre-sortedRedshift 不会将新加载的数据识别为预排序的
【发布时间】:2017-02-17 20:39:17
【问题描述】:

我正在尝试将大量数据加载到 redshift 中,加载到单个表中,一旦加载,这对于 Vacuum 来说成本太高。为了避免清理这个表,我使用 COPY 命令从大量预先排序的 CSV 文件中加载数据。我正在加载的文件是根据表中定义的排序键预先排序的。

然而,在加载前两个文件后,我发现 redshift 将表格报告为 ~50% 未排序。我已验证文件中的数据是否按正确的排序顺序排列。为什么 redshift 不会将新传入的数据识别为已排序? 我是否需要做一些特别的事情来让复制命令知道这个新数据已经处于正确的排序顺序?

我正在使用 SVV_TABLE_INFO 表来确定排序百分比(使用未排序的字段)。排序键是三个不同字段(平面、x、y)的复合键。

Redshift 支持的官方回答:

这是我们官方所说的: http://docs.aws.amazon.com/redshift/latest/dg/vacuum-load-in-sort-key-order.html

当您的表定义了排序键时,该表分为 2 地区:

  • 已排序,并且
  • 未分类

只要您按排序键顺序加载数据,即使数据是 在未排序的区域,它仍然是排序键顺序,所以没有 需要 VACUUM 来确保数据已排序。仍然需要一个 VACUUM 将数据从未排序区域移动到已排序区域, 然而,这不太重要,因为未排序区域中的数据是 已经排序了。

【问题讨论】:

  • 如果您不介意,一些问题可以帮助您解决这个问题……您是如何查询未排序数据的比例的?表的SORTKEY 是否设置为包含每条记录的时间戳的列?您是否检查过与每个区块的区域地图关联的最小值和最大值以确定重叠?
  • @JohnRotenstein 我查询了 SVV_TABLE_INFO 表的未排序字段。排序键实际上是使用 3 个字段的复合键。我还不知道区域地图。会查的。
  • @JohnRotenstein 您能否指出有关如何查询区域地图的资源。它们看起来很有趣,但谷歌搜索并没有显示查询它们的明显方式。

标签: amazon-redshift


【解决方案1】:

在 Amazon Redshift 表中存储排序的数据会在几个方面产生影响:

  • 不使用ORDER BY 时数据如何显示
  • 使用ORDER BY 时对数据进行排序的速度(例如,如果大部分是预排序的,排序会更快)
  • 从磁盘读取数据的速度,基于区域映射

虽然您可能希望选择提高排序速度的SORTKEY(例如Change order of sortkey to descending),但SORTKEY 的主要好处是通过使用区域最小化磁盘访问来使查询运行得更快地图

我承认似乎没有很多关于区域地图如何工作的文档,所以我会在这里尝试解释一下。

Amazon Redshift 以 1MB 块的形式将数据存储在磁盘上。每个块包含与一个表的一列相关的数据,该列的数据可以占用多个块。块可以被压缩,因此它们通常包含超过 1MB 的数据。

磁盘上的每个块都有一个关联的区域图,用于标识该块中要存储的列的最小值和最大值。这使 Redshift 能够跳过不包含相关数据的块。例如,如果SORTKEY 是时间戳,并且查询具有将数据限制在特定日期的WHERE 子句,则 Redshift 可以跳过所需日期不在该块内的任何块。

一旦 Redshift 找到具有所需数据的块,它会将这些块加载到内存中,然后将对加载的数据执行查询。

当它只需要从磁盘加载尽可能少的块时,查询将在 Redshift 中运行得最快。因此,最好使用通常匹配WHERE 子句的SORTKEY,例如数据通常受日期范围限制的时间戳。有时将SORTKEY 设置为与DISTKEY 相同的列是值得的,即使它们用于不同的目的。

可以通过STV_BLOCKLIST 虚拟系统表查看区域地图。此表中的每一行包括:

  • 表 ID
  • 列 ID
  • 区块编号
  • 存储在此块中的字段的最小值
  • 此块中存储的字段的最大值
  • 已排序/未排序标志

我怀疑在清空表后设置了 Sorted 标志。但是,表不一定需要被清理。例如,如果数据始终按时间戳顺序附加,则数据已经在磁盘上排序,从而使区域地图能够最有效地工作。

您提到您的 SORTKEY 是“使用 3 个字段的复合键”。这可能不是最好的 SORTKEY 使用。可能值得对具有不同 SORTKEY 的表运行一些计时测试,以确定复合 SORTKEY 是否比使用单个 SORTKEY 更好。如果所有 3 个字段都经常在 WHERE 子句中使用,那么复合键可能会表现最好。

【讨论】:

  • 我试图从 sortkey 获得的主要好处是查询和连接这三列(总是指定所有三列)尽可能快。因此,如果我对您的理解正确,您是说 redshift 无法识别我的数据是按排序顺序加载的可能并不重要,区域图将帮助我自动从排序数据中受益,作为我的最小/最大值会不会重叠?令人惊讶的是,我无法通过红移识别它。
  • 如果“无法让红移识别它”是指未排序的百分比,它只是自上次排序以来更改/添加的块的计数。这不一定是坏事,但你可以通过测试来证明。至于让查询和连接以最快的速度工作,您应该使用DISTKEY 来改进 JOIN 时间,并使用 SORTKEY 来改进 WHERE 子句(或对两者使用相同的字段以进一步提高 JOIN 速度)。很有可能使用复合 SORTKEY 实际上会减慢您的查询速度,尤其是当该列不用于其他任何操作时。
  • 接受您的回答,因为它已得到 RS 支持的确认。
猜你喜欢
  • 2021-05-15
  • 1970-01-01
  • 2015-12-13
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 2015-09-16
  • 1970-01-01
相关资源
最近更新 更多