Amazon Redshift
数据库开发人员指南 (API Version 2012-12-01)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。点 击 Getting Started with Amazon AWS to see specific differences applicable to the China (Beijing) Region.

步骤 4:选择分配方式

将数据加载到表中时,Amazon Redshift 根据表的分配方式将表中的行分配到各个节点切片。每个节点的切片数取决于集群的节点大小。例如,您在本教程中使用的 dc1.large 集群拥有四个节点,每个节点包含两个切片,因此,该集群总共有八个切片。所有节点均参与并行查询执行,处理跨切片分布的数据。

在执行查询时,查询优化程序根据执行联接和聚合的需要将行重新分配到计算节点。重新分配可能涉及将特定的行发送到节点以进行联接,或将整个表广播到所有节点。

您应指派分配方式以实现上述目标。

  • 并置联接表中的行

    如果联接列的行位于相同的切片上,则查询执行期间需要移动的数据会较少。

  • 在集群中的切片上均匀分配数据。

    如果数据分配均匀,则可将工作负载均匀分配到所有切片。

这些目标在某些情况下可能冲突,您将需要评估哪项策略是整个系统性能的最佳选择。例如,EVEN 分配可能会将某列的所有匹配值放置在同一个切片上。如果某查询针对该列使用相等性筛选条件,则具有这些值的切片将承载不成比例的工作量。如果表基于分配键并置,则分配到切片的行可能不均匀,因为键在整个表中的分配是不均匀的。

在此步骤中,您将根据数据分配目标评估 SSB 表的分配,然后为表选择最佳的分配方式。

分配方式

创建表时,您需要指定三种分配方式之一:KEY、ALL 或 EVEN。

KEY 分配

根据一列中的值分配行。领导节点会尝试将匹配的值放置到同一个节点切片上。如果基于联接键分配一对表,领导节点会根据联接列中的值在切片上并置行,使共同列的匹配值实际存储在一起。

ALL 分配

向每个节点分配整个表的副本。EVEN 分配或 KEY 分配只将表中的部分行放置在每个节点上,而 ALL 分配则确保为该表参与的所有联接并置每一行。

EVEN 分配

不管任意特定列中的值是什么,系统都以轮询方式向所有切片分配行。当表不参与联接或无法明确地在 KEY 分配和 ALL 分配之间做出选择时,即可使用 EVEN 分配。EVEN 分配是默认分配方式。

有关更多信息,请参阅 分配方式

选择分配方式

在执行查询时,查询优化程序根据执行联接和聚合的需要将行重新分配到计算节点。通过在执行查询前将数据放置到需要的位置,可以尽量减少重新分配步骤产生的影响。

首要目标是通过分配数据,使联接表的匹配行得到并置,也就是说,将联接表的匹配行放置到同一个节点切片上。

  1. 要查找查询计划中的重新分配步骤,请执行 EXPLAIN 命令,后跟要检查的查询。此示例使用了我们测试查询集中的查询 2。

    Copy
    explain select sum(lo_revenue), d_year, p_brand1 from lineorder, dwdate, part, supplier where lo_orderdate = d_datekey and lo_partkey = p_partkey and lo_suppkey = s_suppkey and p_category = 'MFGR#12' and s_region = 'AMERICA' group by d_year, p_brand1 order by d_year, p_brand1;

    下面显示了查询计划的部分内容。查找以 DS_BCASTDS_DIST 标签开头的标签

    Copy
    QUERY PLAN XN Merge (cost=1038007224737.84..1038007224738.54 rows=280 width=20) Merge Key: dwdate.d_year, part.p_brand1 -> XN Network (cost=1038007224737.84..1038007224738.54 rows=280 width=20) Send to leader -> XN Sort (cost=1038007224737.84..1038007224738.54 rows=280 width=20) Sort Key: dwdate.d_year, part.p_brand1 -> XN HashAggregate (cost=38007224725.76..38007224726.46 rows=280 -> XN Hash Join DS_BCAST_INNER (cost=30674.95..38007188507.46 Hash Cond: ("outer".lo_orderdate = "inner".d_datekey) -> XN Hash Join DS_BCAST_INNER (cost=30643.00..37598119820.65 Hash Cond: ("outer".lo_suppkey = "inner".s_suppkey) -> XN Hash Join DS_BCAST_INNER Hash Cond: ("outer".lo_partkey = "inner".p_partkey) -> XN Seq Scan on lineorder -> XN Hash (cost=17500.00..17500.00 rows=56000 -> XN Seq Scan on part (cost=0.00..17500.00 Filter: ((p_category)::text = -> XN Hash (cost=12500.00..12500.00 rows=201200 -> XN Seq Scan on supplier (cost=0.00..12500.00 Filter: ((s_region)::text = 'AMERICA'::text) -> XN Hash (cost=25.56..25.56 rows=2556 width=8) -> XN Seq Scan on dwdate (cost=0.00..25.56 rows=2556

    DS_BCAST_INNER 表示内部联接表已广播到所有切片。DS_DIST_BOTH 标签(如果存在)表示外部联接表和内部联接表都已在各切片间重新分配。对查询性能来说,广播和重新分配都是代价高昂的步骤。您需要选择能够减少或消除广播和分配步骤的分配策略。有关评估 EXPLAIN 计划的更多信息,请参阅评估查询模式

  2. 根据共同列分配事实数据表和一个维度表。

    下图显示了 SSB schema 中事实数据表 LINEORDER 及维度表之间的关系。

    每张表都只能拥有一个分配键,这意味着:schema 中只有一对表能够基于其共同列并置。毫无疑问,中央事实数据表是最佳选择。对于表对中的第二张表,选择通常联接事实数据表的最大维度。在此设计中,LINEORDER 是事实数据表,PART 是最大维度。PART 基于其主键 p_partkey 联接 LINEORDER。

    指定 lo_partkey 作为 LINEORDER 的分配键,指定 p_partkey 作为 PART 的分配键,以便在加载数据时,联接键的匹配值能够在相同的切片上并置。

  3. 将一些维度表改为使用 ALL 分配。

    如果某个维度表不能与事实数据表或其他重要的联接表并置,通常,您可以通过将整个表分配到所有节点来大大提高查询性能。ALL 分配可确保联接行在每个切片上并置。在选择 ALL 分配之前,您应权衡所有因素。使用 ALL 分配会使存储空间需求成倍增长,并且会增加加载时间和维护操作。

    CUSTOMER、SUPPLIER 和 DWDATE 也基于其主键联接 LINEORDER 表;但是,LINEORDER 会与 PART 并置,因此,您将设置其余的表使用 DISTSTYLE ALL。这些表相对较小且更新不频繁,因此,使用 ALL 分配对存储空间和加载时间的影响最小。

  4. 为剩余的表使用 EVEN 分配。

    所有表都指定了 DISTKEY 或 ALL 分配方式,因此,您不再为任何表指定 EVEN。但在评估性能结果后,您可能会决定将某些表从 ALL 分配改为 EVEN 分配。

下面的优化表显示了所选择的分配方式。

表名称 排序键 分配方式
LINEORDER lo_orderdate lo_partkey
PART p_partkey p_partkey
CUSTOMER c_custkey ALL
SUPPLIER s_suppkey ALL
DWDATE d_datekey ALL

有关更多信息,请参阅 选择最佳分配方式

下一步

步骤 5:审查压缩编码