Greenplum是一个大规模并行处理数据库,它由一个master和多个segment组成,其数据按照设定的分布策略分布于各个segment上。数据表的单个行会被分配到一个或多个segment上,可是有这么多的segment,它到底会被分到哪一个或哪些segment上呢?分布策略会告诉咱们。算法
在Greenplum 5中,有2种分布策略:数据库
在Greenplum 6中,添加了另外一个策略:安全
哈希分布:dom
要使用这一策略,须要在建立表使用 “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子句。不然,表的分布策略多是只薛定谔的猫。优化
随机分布:设计
要使用这一策略,须要在建立表使用 “DISTRIBUTED RANDOMLY” 子句。产品
随机分布会将数据行按到来顺序依次循环发送到各个segment上。与哈希分布策略不一样,具备相同值的数据行不必定位于同一个segment上。虽然随机分布确保了数据的平均分布,但只要有可能,应该尽可能选择哈希分布策略,哈希分布的性能更加优良。
复制分布:
这种分布策略是GPDB 6的新增特性。
- Greenplum数据分布和分区策略
要使用这一策略,须要在建立表使用 “DISTRIBUTED REPLICATED” 子句。
Greenplum数据库将每行数据分配到每一个segment上。这种分布策略下,表数据将均匀分布,由于每一个segment都存储着一样的数据行。当您须要在segment上执行用户自定义的函数且这些函数须要访问表中的全部行时,就须要用到复制分布策略。或者当有大表与小表join,把足够小的表指定为replicated也可能提高性能。
请注意,有一个例外:catalog表没有分布策略。
关于3项策略的摘要:
哈希分布 | 随机分布 | 复制分布 | |
---|---|---|---|
适用GP5 / 6 | GP5,GP6 | GP5,GP6 | GP6 |
语句 | DISTRIBUTED BY (column, [ … ]) | DISTRIBUTED RANDOMLY | DISTRIBUTED REPLICATED |
默认策略? | ✔ | ✘ | ✘ |
存储 | 1 segment | 1 segment | N segments |
均匀分布 | 取决于选择的分布键 | ✔ | ✔ |
查询性能 | ✔ | ✘ | - |
如今让咱们看一下分区,对于Greenplum新手用户,分区的概念会很容易地与分布混淆,其实分布与分区有根本上的的不一样。分布是对存储的数据进行物理划分,而分区则是逻辑划分。
分区是经过 “PARTITION BY” 子句完成的,它容许将一个大表划分为多个子表。“SUBPARTITION BY” 子句能够将子表划分为更小的表 。从理论上讲,Greenplum对于根表(root table)能够拥有多少级(level)或多少个分区表(partitioned table)并无限制,可是对于任一级分区(表的层次结构级别),一个分区表最多能够有32,767个子分区表。
当只考虑分布时,能够只把分区表看成一个普通表。对于一个根表来讲,它的数据首先会被分配到某个分区表,而后单个分区表会像普通表同样根据分区表的分布策略分布在Greenplum的各个segments上,这与任何未分区表相同。Greenplum数据库中的表物理地分布在Greenplum各个segments上,使并行查询处理成为可能。表分区是一种逻辑上划分大表的工具,可提升查询性能并促进数据仓库维护任务。分区不会更改表数据在segment之间的物理分布。
Greenplum支持如下分区类型:
对大表进行分区,将提升查询性能并简化数据库的维护任务,例如将旧数据滚动移除出数据库。
可是不要建立超出您须要的分区。建立过多的分区可能会拖慢管理和维护的速度,例如清理,恢复segment,扩展集群,检查磁盘使用状况等等。
除非查询优化器能够根据查询谓词修剪分区,不然使用分区不会提升查询性能。须要依次扫描各个分区表的查询比只需扫描无分区的根表的查询运行得慢,所以,若是你的查询中不多能用上分区裁剪,请尽可能尝试避免对表进行分区。在GPCC中,能够检查查询监视器中的可视计划,以防扫描无关分区。
您还可能会遇到另外一种分区:默认分区。
当进来的数据与全部的分区不匹配时,它将被插入默认分区。若是分区设计没有默认分区,它将拒绝其插入操做。
默认分区是一把双刃剑,有了它,表的操做很安全,可是也可能会掩盖问题。
假设您有一个表,并根据“age”列建立分区。它定义了一个LIST,当数据行的年龄为1时,它进入Partition1;当年龄为2时,它进入Partition2,…,当年龄为100时,它进入Partition100。可是有一天,一个101岁的人来了,BANG,错误发生了,由于您还没有为age = 101建立分区,因此也没有partition101表。这我的无处可去。
若是您为该表建立了默认分区,则101岁的老人将转到该默认分区。问题解决了,你们都很开心。
而假设某一天人类的寿命变得更长,好比200岁,那么100岁以上的人都将被分到默认分区。默认分区会被撑的愈来愈大,若是没有人注意,查询就会愈来愈慢,由于该分区太大,以至于分区修剪并没有多大效果。
既然表的这些分布和分区策略如何重要,您可能会问:咱们如何监控这些状况,以及及早发现异常。
咱们将在下一篇《GPCC如何提供帮助》详细解答。