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 的自然分布键(通常是 customer
或 account
)。
我有一个缓慢变化的维度,代表我们所有的文章主数据变化,而且非常庞大: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 的自然分布键(通常是 customer
或 account
)。