【发布时间】:2015-06-05 11:30:41
【问题描述】:
我在 Redshift 中有一个事实表,其中包含大约 13 亿行,其中包含 DISTribution 键 c1 和排序键 c1、c2。
我需要在 c1 上使用 join 子句将这个表与其自身连接起来(即来自第一个表实例的 c1 = 来自第二个表实例的 c1)。
当我看到我的查询的查询计划时,Redshift 似乎正在使用 DS_DIST_NONE 进行哈希联接。虽然 DS_DIST_NONE 是预期的,因为我在 c1 列上同时具有 dist 键和排序键,但我希望 Redshift 执行 Merge Join 而不是 Hash Join(再次因为相同的原因)。
我相信这会减慢我的查询速度。
谁能解释一下为什么 Redshift 可能正在执行 Hash Join 而不是 Merge Join(即使我在连接列上有 DIST Key 和 SORT key)而 Redshift 正在为查询执行 DS_DIST_NONE?
【问题讨论】:
-
为什么c1上同时有dist key和sort key? dist 键应位于高基数列上,用于在节点之间均匀分布数据,而排序键应位于低基数列上,因为它用于更快地扫描和跳过数据。
-
在“c1”上加入时,必须将相同的列(“c1”)作为 dist 键和排序键来实现合并排序。这在 Amazon Redshift 文档中有所提及。我也无法理解为什么需要“c1”的低基数以允许更快地扫描和跳过数据。你能解释一下吗?
-
对于 JOIN,您需要将连接表的两个键都定义为分布键,以允许在每个节点中进行并置连接。排序键允许在过滤时更快地扫描数据以找到相关数据(WHERE ...)。将 c1 作为 JOIN 查询的排序键几乎没有什么好处。 SORT 键告诉 Redshift 如何对磁盘上的数据进行排序。它使元数据(例如,每个数据块的最小值和最大值)与查询相关,以忽略大多数没有在 WHERE 子句中定义的值的数据块。
-
根据 Redshift Best Practices Documentation,对 SORT 和 DIST 键使用一列是一种有效的方法,特别是如果您希望经常连接两个表。当然,如果该表更多地用于过滤查询,那么最有可能被过滤的列上的排序键可能是一个更好的选择。两者都是有效的方法。至于为什么查询计划不使用合并连接:有很多可能的原因。发布查询、表模式和 EXPLAIN 是调试的第一步。
-
事实证明,由于我们没有按排序顺序(由该表的排序键定义)在表中插入数据,并且 Redshift 不会自动保持表的行按排序键排序,所以没有Redshift 在我们的表上执行 Merge Join 的方式。在表上运行 Full Vacuum 后,Redshift 开始执行 Merge Join。
标签: sql join amazon-web-services hash amazon-redshift