Redshift Dist 键、IDentity 列或连接列?列的基数,用于排序键的联接考虑

Posted

技术标签:

【中文标题】Redshift Dist 键、IDentity 列或连接列?列的基数,用于排序键的联接考虑【英文标题】:Redshift Dist key, IDentity column or join column? Cardinality of Column, Used in Join consideration for sort Key 【发布时间】:2018-11-28 08:40:09 【问题描述】:

我有一个表,其中有一个名为 ID 的标识列和另一个名为 DateID 的列,该列引用另一个表。

日期列用于连接,但 ID 列具有更多基数。

ID 列的不同计数:657167 DateID 列的不同计数:350

任何人都可以就哪一列作为分发密钥的更好选择提供任何见解吗?


*另外关于另一个问题: 我在选择表中的 sort 和 dist 键时进退两难。 排序键 选择排序键时是否应该考虑基数?

将与其他表连接的列将成为排序键的候选者,我的假设是否正确? 如果我使用复合排序键并使用两列,那么列的顺序是否重要? 如果我将 DateID 列定义为 dist 键,我应该在定义复合排序键时将 DateID 放在 customerId 前面吗?*

另一个问题合并到这个旧问题,因为它们是相关的。


附:我读了一些关于选择 dist 键的文章,他们说我应该使用一个用于与其他表连接并且具有更大基数的列。

SELECT SP.*, CP.*, TV.* FROM ( SELECT * --> there are about 20 aggregation statements in the select statement FROM FactCustomer f -- contains about 600K records JOIN DimDate d -- contains about 700 records ON f.DateID = d.DateID JOIN DimTime t -- contains 24 records ON f.TimeID = t.HourID JOIN DimSalesBranch s -- contains about 64K records ON f.BranchID = s.BranchID WHERE s.BranchID IN ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ) AND d.DateTimeInfo >= (CASE WHEN s.OpeningDate > '2018-01-01' THEN s.OpeningDate ELSE '2018-01-01' END ) AND d.DateTimeInfo <= '2018-12-31' AND StartHour >= 9 AND starthour > 0 AND (EndHour <= 22) ) SP LEFT JOIN ( SELECT * --> there are about 20 aggregation statements in the select statement FROM FactCustomer f JOIN DimDate d ON f.DateID = d.DateID JOIN DimTime t ON f.TimeID = t.HourID JOIN DimSalesBranch s ON f.BranchID = s.BranchID WHERE s.BranchID IN ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ) AND d.DateTimeInfo >= (CASE WHEN s.OpeningDate > '2018-01-01' THEN s.OpeningDate ELSE '2018-01-01' END ) AND d.DateTimeInfo <= '2018-09-16' AND StartHour >= 9 AND (EndHour <= 22) ) CP ON SP.StartDate = CP.StartDate_CP AND SP.EndDate = CP.EndDate_CP LEFT JOIN ( SELECT * --> there are about 6 aggregation statements in the select statement FROM FactSalesTargetBranch f JOIN DimDate d ON f.DateID = d.DateID JOIN DimSalesBranch s ON f.BranchID = s.BranchID WHERE s.BranchID IN ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ) AND d.DateTimeInfo >= (CASE WHEN s.OpeningDate > '2018-01-01' THEN s.OpeningDate ELSE '2018-01-01' END ) AND d.DateTimeInfo <= '2018-09-16' ) TV ON SP.StartDate = TV.StartDate_TV AND SP.EndDate = TV.EndDate_TV;

非常感谢任何见解。

问候。

【问题讨论】:

你加入 dateid 的目的是什么?日期表? 是的,它加入了一个日期表。我有很多带有 dateID 列的表,它们与日期表本身以及其他表连接。你会推荐使用按 dateID 列均匀分布吗? 是的“偶数”分布 - 请注意,“偶数”分布不需要列 多个大表之间是否有任何大连接? 我的表中的数据高达 1000 万(多个表的数据量如此之大),我不确定什么会被认为是一个大表,请您提供您的见解吗?在我的帖子中的示例中,日期表包含大约 700 行,而事实表包含大约 600K 记录。鉴于这样的记录,我什至应该使用 dist 键吗?。 【参考方案1】:

在这种情况下

    为您的主表使用“均匀”分布,这将允许良好的 并行性。 (dateid 将是一个糟糕的候选人) 对您的 dateid 表(较小的表)使用“全部”分布 你加入)

一般来说,“均匀”分布是一个不错的选择,除非您需要将大表连接在一起,否则它会给您最好的结果。

见https://docs.aws.amazon.com/redshift/latest/dg/c_choosing_dist_sort.html

【讨论】:

感谢乔恩的洞察力。 ID 和 dateID 列来自我的事实表。 - 你会推荐使用均匀分布到我的事实表,然后“全部”分布到我的日期表吗? - 另外,如果您不介意,请告诉我应该将什么视为“大桌子”?一张大表有多少行? large = 数百万行,如果您使用的是 1 节点红移系统,是的,这正是我在答案中所说的。 嘿@jon-scott,我在一个 1 集群 2 节点红移系统上。我尝试了所有日期表的 dist 样式和 dist 样式,即使是我的事实表。我没有看到执行周期有任何变化,但可能是因为查询编译缓存(我已关闭结果缓存以进行基准测试)。我会重新测试和检查。如果您不介意,我的另一个查询是,如果我有 5 个事实表并且我经常使用这些表并使用相同的连接列连接维度表。您是否建议对我的所有事实表使用均匀分布,因为到目前为止我的系统中没有太多数据? 请问您可以将您正在使用的 sql 添加到您的问题中吗?另外 - 查询需要多长时间(以秒为单位)?最后,您需要的速度是多少? 嘿@jon,我对速度的实际要求是通过优化使我的第一次执行尽可能快mysql 中的相同数据在 10 秒内运行,并且在 redshift 中需要相同或更多的时间。我的理解是 redshift 查询应该比 mysql 快得多。 即使是第一次执行。我的主要目标是让第一次执行在 ms 内运行。我有一组加载到仪表板的查询,我想让它们尽快加载到仪表板中。我将尝试在此处发布我的 sql 供您查看。再次非常感谢您的所有意见:)

以上是关于Redshift Dist 键、IDentity 列或连接列?列的基数,用于排序键的联接考虑的主要内容,如果未能解决你的问题,请参考以下文章

Redshift - 重新设计表以使用 DIST 和 SORT 键(性能问题)

当两个表具有相同的 dist 和 sort 键,但列名不同时,Redshift 是不是执行合并连接?

Redshift 时间序列数据库的 Dist/Sort 键

Redshift:主表的 DIST KEY 和 SORT KEY 的适当组合是啥?

如果我使用 COPY 命令将数据从 S3 加载到 Redshift,它会遵循我的 dist 样式和键吗?

Redshift:sortkey 和 distkey 可以为空吗?