数据仓库服务 GAUSSDB(DWS)-CREATE TABLE:DISTRIBUTE BY参数使用说明
DISTRIBUTE BY参数使用说明
指定表如何在节点之间分布或者复制。
取值范围:
- REPLICATION:表的每一行存在所有数据节点(DN)中,即每个数据节点都有完整的表数据。
- ROUNDROBIN:表的每一行被轮番地发送给各个DN,因此数据会被均匀地分布在各个DN中。(ROUNDROBIN仅8.1.2及以上版本支持)
- HASH (column_name ) :对指定的列进行Hash,通过映射,把数据分布到指定DN。
- 当指定DISTRIBUTE BY HASH (column_name)参数时,创建主键和唯一索引必须包含“ column_name”列。
- 当被参照表指定DISTRIBUTE BY HASH (column_name)参数时,参照表的外键必须包含“ column_name”列。
- 如果TO GROUP指定为复制表节点组(8.1.2及以上版本支持),DISTRIBUTE BY必须指定为REPLICATION。如果没有指定DISTRIBUTE BY,创建的表会自动设置为复制表。
- 单节点集群(单机部署)由于只有单DN,因此分布规则会被忽略,也不支持针对分布规则的修改。
- 当default_distribution_mode=roundrobin时,DISTRIBUTE BY的默认值按如下规则选取:
- 若建表时包含主键/唯一约束,则选取HASH分布,分布列为主键/唯一约束对应的列。
- 若建表时不包含主键/唯一约束,则选取ROUNDROBIN分布。
- 当default_distribution_mode=hash时,DISTRIBUTE BY的默认值按如下规则选取:
- 若建表时包含主键/唯一约束,则选取HASH分布,分布列为主键/唯一约束对应的列。
- 若建表时不包含主键/唯一约束,但存在数据类型支持作分布列的列,则选取HASH分布,分布列为第一个数据类型支持作分布列的列。
- 若建表时不包含主键/唯一约束,也不存在数据类型支持作分布列的列,选取ROUNDROBIN分布。
- INTEGER TYPES:TINYINT,SMALLINT,INT,BIGINT,NUMERIC/DECIMAL
- CHARACTER TYPES:CHAR,BPCHAR,VARCHAR,VARCHAR2,NVARCHAR2,TEXT
- DATE/TIME TYPES:DATE,TIME,TIMETZ,TIMESTAMP,TIMESTAMPTZ,INTERVAL,SMALLDATETIME

在建表时,选择分布列和分区键可对SQL查询性能产生重大影响。因此,需要根据一定策略选择合适的分布列和分区键。
- 选择合适的分布列
对于采用散列(Hash)方式的数据分布表,一个合适的分布列应将一个表内的数据,均匀分散存储在多个DN内,避免出现数据倾斜现象(即多个DN内数据分布不均)。请按照如下原则判定合适的分布列:
- 判断是否已发生数据倾斜现象。
连接数据库,执行如下语句,查看各DN内元组数目。命令中的斜体部分tablename,请填入待分析的表名。
SELECT a.count,b.node_name FROM (SELECT count(*) AS count,xc_node_id FROM tablename GROUP BY xc_node_id) a, pgxc_node b WHERE a.xc_node_id=b.node_id ORDER BY a.count DESC;
如果各DN内元组数目相差较大(如相差数倍、数十倍),则表明已发生数据倾斜现象,请按照下面原则调整分布列。
- 重新选择分布列,可通过ALTER TABLE语句调整分布列,选择原则如下:
分布列的列值应比较离散,以便数据能够均匀分布到各个DN。例如,考虑选择表的主键为分布列,如在人员信息表中选择身份证号码为分布列。
在满足上面原则的情况下,考虑选择查询中的连接条件为分布列,以便Join任务能够下推到DN中执行,且减少DN之间的通信数据量。
- 如果找不到一个合适的分布列,使数据能够均匀分布到各个DN,那么可以考虑使用REPLICATION或ROUNDROBIN的数据分布方式。由于REPLICATION的数据分布方式会在每个DN中存放完整的数据,因此在表较大且找不到合适的分布列时,推荐使用ROUNDROBIN的数据分布方式。(ROUNDROBIN分布方式8.1.2及以上版本支持)
- 判断是否已发生数据倾斜现象。
- 选择合适的分区键
数据分区功能,可根据表的一列或者多列,将要插入表的记录分为若干个范围(这些范围在不同的分区里没有重叠)。然后为每个范围创建一个分区,用来存储相应的数据。
调整分区键,使每次查询结果尽可能存储在相同或者最少的分区内(称为“分区剪枝”),通过获取连续I/O大幅度提升查询性能。
实际业务中,经常将时间作为查询对象的过滤条件,因此,可考虑选择时间列为分区键,键值范围可根据总数据量、一次查询数据量调整。