Redshift:范围连接的 DIST KEY 和 SORT KEY 策略

Redshift: DIST KEY and SORT KEY strategy for Range Joins

我有一个缓慢变化的维度,代表我们所有的文章主数据变化,而且非常庞大:150 亿行并且还在增长。

table 目前分布在自然合奏中,例如(国家、供应商)。

由于 table 的性质,使用它的大多数查询都是范围连接,例如根据不断变化的文章属性对订单进行简单计数:

SELECT x.article_id, x.changing_article_season, COUNT(*) counting_orders
FROM article_slow_changing_dimension x
LEFT JOIN orders y ON x.article_id=y.article_id
AND y.order_timestamp BETWEEN x.from_timestamp AND y.to_timestamp

在这里选择排序键有什么有趣的策略? 我正在考虑做 SORTKEY(from_timestamp, to_timestamp) 但我不确定。

我尝试了一些东西,但任何测试都需要很长时间才能设置,而且实际上很难根据经验进行评估。有什么想法吗?

编辑:根据评论添加一些细节 1/ tables 被吸尘 2/ 集群非常小(4 个节点),查询运行得非常快,但它不在生产环境中,所以基本上只有我这些开发人员 运行 有几个查询。我想在投入生产之前进行优化 3/ 现在大约有 150 亿行,聚合特定时间戳需要 1 分钟;但我想将其缩短到 20 秒

好问题。

一点背景知识,排序键有 2 个主要目的:1) 最小化从磁盘扫描的数据和 2) 使大型 table 之间的连接能够使用合并连接(最快的连接)。 https://docs.aws.amazon.com/redshift/latest/dg/query-performance-improvement-opportunities.html

SORTKEY(from_timestamp, to_timestamp) 通常是一个很好的选择,但它不会提高示例查询的性能。在像 WHERE from_timestamp > '2019-01-01' AND to_timestamp < current_date.

这样的谓词中使用这些字段的情况下,它会更有帮助

您可以优化这种范围连接的程度是有限制的,因为数据库必须将其视为笛卡尔积(又名 "CROSS JOIN" - 将 a 中的每一行与每个来自 b 的行)。您知道连接将匹配单个行,但数据库不知道

在全维度 DW 中,我会创建一个 article_sk 代理键。该值将解析为 SCD 中的一个值。这使 ETL 过程变得复杂,因为您必须在处理过程中注入代理键。

您可以做的另一件事是使用 article 列分发两个 table。这允许在每个切片上并行完成连接。但是,article 可能不是您的 orders 事实 table 的自然分布键(通常是 customeraccount)。