greenplum是基于postgre的数据库,最大的特征就是分布式,多节点(segment)。保存的数据会根据分布键存储到不同的节点上,用于查询或者关联。如果分布键选择得当,数据散列均匀,各个节点的数据量就会保持平衡,量级基本一致。如果选择不当就是导致数据倾斜,某一个节点数据量特别大。直接影响就是木桶效应,其他节点不工作,一个节点处理所有的数据,再提交给master,效率低下。理想状态下关联表分布键相同,在同一节点进行关联提交MASTER。

 

Greenplum分布键方式:

Hash分布:选择一个或多个列作为分布键,计算 hash 值,并通过 hash 值路由到特定的Segment节点上。如果不指定分布键,默认将第一个字段作为分布键。

随机分布:数据随机分散在每一个节点中,可以保证数据平均分布,但是在执行 SQL 的过程中,关联等操作都需要将数据重分布,性能较差。

 

 


分布键的创建:

  1.     DISTRIBUTED BY(字段1,字段2)指定字段作为分布键
  2.     变更分布键(ALTER TABLE 表明 set distributed by(字段1,字段2)),执行后会重新分布节点上的数据。
  3.     建表时不指定DISTRIBUTED BY 第一个字段就是分布键。

分布键的选择:

经常需要 JOIN 的列

当关联键和分布键均一致时,可以在 Segment 中完成 JOIN,不需要重分布或者广播表(左连接  不能将左表广播,右连接  不能将右表广播,全连接时,两表不允许广播

当关联键和分布键不一致时,则需要重分布不一致的表或者广播表,带来额外的开销。

          例:左分布键 关联 右非分布键

Greenplum 分区表自动管理 greenplum 分区表和分布键_数据

      无分布键进行关联:

Greenplum 分区表自动管理 greenplum 分区表和分布键_数据倾斜_02

 选择分布键关联代价会减少。

 

分布均匀的列或者多列

选择的分布列值单一,则可能导致数据倾斜,更有可能全部倾斜到一个节点上。master会等待所有的segment提交数据后返回结果,小的节点立即提交,但是大的节点会浪费很多时间。所以一次SQL执行的时间无形中被延长了。

若表中没有分布太均匀的字段 就多个字段进行组合分布。

查询数据倾斜状态: select gp_segment_id,count(*) from ods_events GROUP BY gp_segment_id;

高并发查询的条件列

如果数据经常被高并发的键值或离散查询,可以将查询条件的列作为分布列,这样不需要连接到所有的 Segment 去查,可以大大提高并发能力。

不要轻易使用随机分布

 随机分布,单表使用还好,如果多表管理,就是上图(无分布键进行关联)的效果了。多节点重分布。。。效率低下

不会被修改的字段

程序中也应注意,分布键不能出现在update语句中,半自动修改数据的时候要避开分布键,不要出现在被修改的字段中。