5 Greenplum表的管理实践-2 表分布策略
文章目录
本文主要从表的分布策略,Greenplum是一个大规模并行处理数据库,它由一个master和多个segment组成,其数据按照设定的分布策略分布于各个segment上。数据表的单个行会被分配到一个或多个segment上,但是有这么多的segment,它到底会被分到哪个或哪些segment上呢?分布策略会告诉我们。
5.1 表分布策略
在 Greenplum 5 中,有2种分布策略:
- 哈希分布
- 随机分布
在 Greenplum 6 中,添加了另一个策略:
- 哈希分布
- 随机分布
- 复制分布
哈希分布
要使用这一策略,需要在创建表使用 “DISTRIBUTED BY(column,[…])” 子句。
散列算法使分布键将每一行分配给特定 segment。相同值的键将始终散列到同一个 segment。选择唯一的分布键(例如Primary Key)将确保较均匀的数据分布。哈希分布是表的默认分布策略。
如果创建表时未提供 DISTRIBUTED 子句,则将 PRIMARY KEY(如果表真的有的话)或表的第一个合格列用作分布键。什么类型的列是合格列呢?几何类型或用户自定义数据类型的列不能用作 Greenplum 分布键列。如果表中没有合格的列,则退化为随机分布策略。
但是,如果未提供 DISTRIBUTED 子句,Greenplum 最后会选择哪种分布策略还会受其它因素的影响,例如:GUC gp_create_table_random_default_distribution 和当时使用的优化器(optimizer)也将影响最终决定。因此,请千万不要忘记在 CREATE TABLE 时添加 DISTRIBUTED BY 子句
。
Note: 如果创建表时没有指定DISTRIBUTED BY,Greenplum数据库服务器配置参数
gp_create_table_random_default_distribution
[gpadmin@mdw ~]$ gpconfig --show gp_create_table_random_default_distribution
Values on all segments are consistent
GUC : gp_create_table_random_default_distribution
Master value: off
Segment value: off
[gpadmin@mdw ~]$
随机分布
要使用这一策略,需要在创建表使用 “DISTRIBUTED RANDOMLY” 子句。
随机分布会将数据行按到来顺序依次循环发送到各个 segment 上。与哈希分布策略不同,具有相同值的数据行不一定位于同一个 segment 上。虽然随机分布确保了数据的平均分布,但只要有可能,应该尽量选择哈希分布策略,哈希分布的性能更加优良。
复制分布
这种分布策略是 GPDB 6 的新增特性。要使用这一策略,需要在创建表使用 “DISTRIBUTED REPLICATED” 子句。
Greenplum 数据库将每行数据分配到每个 segment上。这种分布策略下,表数据将均匀分布,因为每个 segment 都存储着同样的数据行。当您需要在 segment 上执行用户自定义的函数且这些函数需要访问表中的所有行时,就需要用到复制分布策略。或者当有大表与小表 join,把足够小的表指定为 replicated 也可能提升性能。
请注意,有一个例外:catalog 表没有分布策略。
关于3项策略的摘要:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IhPKnWSd-1588921554857)(D:\SYBASE&informix&DB2\Greenplum\4 学习笔记\数据库管理\5 Greenplum表的管理实践-2.assets\3baead233c6f42a4bdc7f48d93c272cc.jpg)]
控制表的分布策略。
更多有关该参数的信息,请见Greenplum数据库参考指南的“服务器配置参数”部分。
在决定表分布策略时,请考虑以下几点。
- 均匀数据分布 — 为了最好的性能,所有的Segment应该包含等量的数据。如果数据不平衡或者倾斜,具有更多数据的Segment就必须做更多工作来执行它那一部分的查询处理。 请选择对于每一个记录都唯一的分布键,例如主键。
- 本地和分布式操作 — 本地操作比分布式操作更快。在Segment层面上,如果与连接、排序或者聚集操作相关的工作在本地完成,查询处理是最快的。在系统层面完成的工作要求在Segment之间分布元组,其效率会低些。当表共享一个共同的分布键时,在它们共享的分布键列上的连接或者排序工作会在本地完成。对于随机分布策略来说,本地连接操作就行不通了。
- 均匀查询处理 — 为了最好的性能,所有的Segment应该处理等量的查询负载。如果一个表的数据分布策略与查询谓词匹配不好,查询负载可能会倾斜。例如,假定一个销售事务表按照客户ID列(分布键)分布。如果查询中的谓词引用了一个单一的客户ID,该查询处理工作会被集中在一个Segment上。
选择法则:
1)尽量选择经常需要 JOIN 的列
当关联键和分布键均一致时,可以在 Segment 中完成 JOIN,不需要重分布或者广播小表。
当关联键和分布键不一致时,则需要重分布不一致的表或者广播小表,带来额外的开销。
2)尽量选择分布均匀的列或者多列
若选择的分布列值分布不均匀,则可能导致数据倾斜。某些 Segment 非常大(压力大),某些 Segment 非常小。根据木桶原理,时间消耗会卡在数据多的节点上。
3)尽量选择高并发查询的条件列(指该查询条件产生的中间结果集小的,如果中间结果集很大,那就让所有节点都来参与运算更好,因此不选)
如果数据经常被高并发的键值或离散查询,可以将查询条件的列作为分布列,这样不需要连接到所有的 Segment 去查,可以大大提高并发能力。
4)不要轻易使用随机分布
复制表分布策略(DISTRIBUTED REPLICATED)应该在小表上使用。 将大表数据复制到每个节点上无论在存储还是维护上都是有代价的。 复制表最基本的用例是:
- 删除用户定义的函数可以对节点执行的操作的限制
- 频繁使用的表不需要广播到所有节点可以提高查询性能。
声明分布键
CREATE TABLE命令的可选子句DISTRIBUTED BY, DISTRIBUTED RANDOMLY和DISTRIBUTED REPLICATED决定了表的分布策略。默认的哈希分布策略使用PRIMARY KEY(如果有的话)或表的第一列作为分布键。几何信息列或用户自定义数据类型的列是不能作为Greenplum数据库分布列的。 如果找不到合适的哈希分布的列,Greenplum数据库就选择随机分布策略。
复制表没有分布列,因为每行都分布在Greenplum数据库所有节点上。
为了保证哈希分布数据的均匀分布,最好选一个唯一键作为分布列。如果找不到,则选择DISTRIBUTED RANDOMLY。例如:
=> CREATE TABLE products
(name varchar(40),
prod_id integer,
supplier_id integer)
DISTRIBUTED BY (prod_id);
=> CREATE TABLE random_stuff
(things text,
doodads text,
etc text)
DISTRIBUTED RANDOMLY;
Important: 主键总是表的分布列。如果没有主键,但是有唯一索引存在,则选择它为分布键。
自定义分布键哈希函数
用于哈希分布策略的哈希函数由列的数据类型的哈希运算符类定义。由于默认的Greenplum数据库使用数据类型的默认哈希运算符类,因此用于哈希连接和哈希聚合的运算符类相同,适用于大多数用例。 但是,您可以在DISTRIBUTED BY子句中声明非默认的哈希运算符类。
使用自定义哈希运算符类可以用于支持与默认相等运算符(=)不同的运算符上的共存连接。
自定义哈希操作符类用例
此示例为整数数据类型创建自定义哈希运算符类,该类用于提高查询性能。运算符类比较整数的绝对值。
创建一个函数和一个等于运算符,如果两个整数的绝对值相等,则返回true。
CREATE FUNCTION abseq(int, int) RETURNS BOOL AS
$$
begin return abs($1) = abs($2); end;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
CREATE OPERATOR |=| (
PROCEDURE = abseq,
LEFTARG = int,
RIGHTARG = int,
COMMUTATOR = |=|,
hashes, merges);
现在,创建一个使用运算符的哈希函数和运算符类。
CREATE FUNCTION abshashfunc(int) RETURNS int AS
$$
begin return hashint(abs($1)); end;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
CREATE OPERATOR CLASS abs_int_hash_ops FOR TYPE int4
USING hash AS
OPERATOR 1 |=|,
FUNCTION 1 abshashfunc(int);
并且,为它们创建小于和大于运算符和B树运算符类。我们的查询不需要它们,但是Greenplum数据库的Postgres查询优化器必须依赖它们做连接的co-location。
CREATE FUNCTION abslt(int, int) RETURNS BOOL AS
$$
begin return abs($1) < abs($2); end;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
CREATE OPERATOR |<| (
PROCEDURE = abslt,
LEFTARG = int,
RIGHTARG = int);
CREATE FUNCTION absgt(int, int) RETURNS BOOL AS
$$
be

本文深入探讨Greenplum数据库中的表分布策略,包括哈希分布、随机分布及复制分布,详细解释如何通过分布键控制数据分布,提高查询性能,并提供实际案例演示。
最低0.47元/天 解锁文章
3496

被折叠的 条评论
为什么被折叠?



