

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://www.amazonaws.cn/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# 评估查询计划
<a name="c_data_redistribution"></a>

您可以使用查询计划确定优化分配方式的候选项。

做出初始设计决策后，创建您的表，为它们加载数据，然后测试它们。请使用尽可能接近真实情况的测试数据集。测量加载时间，以用作比较的基准。

评估具有代表性的查询（可代表您希望执行的代价最为高昂的查询）；具体地说，就是使用联接和聚合的查询。比较各设计选项的运行时。如果要比较运行时，请不要将查询的首次执行计算在内，因为第一个运行时包含编译时间。

**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\_ERR**  
当表未选择分配方式时。

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)
```