评估查询计划
您可以使用查询计划确定优化分配方式的候选项。
做出初始设计决策后,创建您的表,为它们加载数据,然后测试它们。请使用尽可能接近真实情况的测试数据集。测量加载时间,以用作比较的基准。
评估具有代表性的查询(可代表您希望执行的代价最为高昂的查询);具体地说,就是使用联接和聚合的查询。比较各设计选项的运行时。如果要比较运行时,请不要将查询的首次执行计算在内,因为第一个运行时包含编译时间。
- DS_DIST_NONE
-
无需重新分配,因为相应的切片已在计算节点上并置。通常,您只有一个 DS_DIST_NONE 步骤:事实数据表与一个维度表之间的联接。
- DS_DIST_ALL_NONE
-
无需重新分配,因为内部联接表使用 DISTSTYLE ALL。每个节点上都有整个表。
- DS_DIST_INNER
-
内部表重新分配。
- DS_DIST_OUTER
-
外部表重新分配。
- DS_BCAST_INNER
-
将整个内部表的副本广播到所有计算节点。
- DS_DIST_ALL_INNER
-
整个内部表重新分配到单个切片,因为外部表使用 DISTSTYLE ALL。
- DS_DIST_BOTH
-
两个表都重新分配。
DS_DIST_NONE 和 DS_DIST_ALL_NONE 都很好。它们表示该步骤无需分配,因为所有联接都已并置。
DS_DIST_INNER 意味着该步骤的成本可能相对较高,因为需要将内部表重新分配到节点。DS_DIST_INNER 表示外部表已根据联接键正确分配。将内部表的分配键设为联接键,以将此转换为 DS_DIST_NONE。在某些情况下,无法根据联接键分配内部表,因为没有根据联接键分配外部表。如果是这种情况,请评估是否对内部表使用 ALL 分配。如果表更新不频繁、不广泛,且表大到足以产生很高的重新分配成本,则将分配方式更改为 ALL 并重新测试。ALL 分配会导致加载时间增加,因此,当您重新测试时,请将加载时间包含在评估因素中。
DS_DIST_ALL_INNER 效果不佳。它表示整个内部表重新分配到单个切片(因为外部表使用 DISTSTYLE ALL),因此,各个节点上都有整个外部表的副本。这会导致在单个节点上低效地顺序执行运行时,而不是使用所有节点来充分利用并行运行时。DISTSTYLE ALL 仅适用于内部联接表。请为外部表指定分配键或使用 EVEN 分配。
DS_BCAST_INNER 和 DS_DIST_BOTH 效果都不好。通常,此类重新分配在表未根据其分配键联接时出现。如果事实数据表还没有分配键,则指定联接列作为这两个表的分配键。如果事实数据表已有基于另一列的分配键,则评估更改分配键以并置该联接能否提高整体性能。如果更改外部表的分配键不是最佳选择,则您可以为内部表指定 DISTSTYLE ALL,从而实现并置。
以下示例显示了具有 DS_BCAST_INNER 和 DS_DIST_NONE 标签的查询计划的部分内容。
-> XN Hash Join DS_BCAST_INNER (cost=112.50..3272334142.59 rows=170771 width=84) Hash Cond: ("outer".venueid = "inner".venueid) -> XN Hash Join DS_BCAST_INNER (cost=109.98..3167290276.71 rows=172456 width=47) Hash Cond: ("outer".eventid = "inner".eventid) -> XN Merge Join DS_DIST_NONE (cost=0.00..6286.47 rows=172456 width=30) Merge Cond: ("outer".listid = "inner".listid) -> XN Seq Scan on listing (cost=0.00..1924.97 rows=192497 width=14) -> XN Seq Scan on sales (cost=0.00..1724.56 rows=172456 width=24)
将维度表更改为使用 DISTSTYLE ALL 后,相同查询的查询计划显示 DS_DIST_ALL_NONE 而不是 DS_BCAST_INNER。此外,联接步骤的相对成本也会有极大的改变。与上一个查询中的 3272334142.59
相比,总成本为 14142.59
。
-> XN Hash Join DS_DIST_ALL_NONE (cost=112.50..14142.59 rows=170771 width=84) Hash Cond: ("outer".venueid = "inner".venueid) -> XN Hash Join DS_DIST_ALL_NONE (cost=109.98..10276.71 rows=172456 width=47) Hash Cond: ("outer".eventid = "inner".eventid) -> XN Merge Join DS_DIST_NONE (cost=0.00..6286.47 rows=172456 width=30) Merge Cond: ("outer".listid = "inner".listid) -> XN Seq Scan on listing (cost=0.00..1924.97 rows=192497 width=14) -> XN Seq Scan on sales (cost=0.00..1724.56 rows=172456 width=24)