本文转载请联系数据云公众号。如果GaussDB采用分布式部署方式,可以根据数据量和使用情况定义两张分布方式不同的表,即复制表(Replication)和散列(Hash)表。复制表(Replication)是在集群的每个DN实例上都保留一份表中全量数据的副本,主要适用于数据量较小的表。这种存储方式的好处是每个DN都有这张表中的全量数据,在Join操作时可以避免数据重新分配操作,从而减少网络开销。缺点是每个DN都保留了表的完整数据,造成数据冗余。一般情况下,只有较小的维度表被定义为复制表。哈希(Hash)表是对表中的一个或几个字段进行哈希运算后生成对应的哈希值,并根据DN实例与哈希值的映射关系得到元组的目标存储位置。对于Hash分布表,读写数据时可以使用每个节点的IO资源,大大提高了表的读写速度。通常,大表被定义为哈希表。Hash分布表的分布列选择很重要,需要满足以下原则:(1)列值要相对离散,这样数据才能均匀分布到各个DN。比如考虑选择表的主键作为分布列,比如在人员信息表中选择身份证号作为分布列。(2)在满足第一原则的情况下,尽量不要选择常量过滤器的列。比如在一些与表dwcjk相关的查询中,dwcjk的列zqdh有一个常量约束(比如zqdh='000001'),所以zqdh尽量不要作为分布列。(3)在满足前两个原则的情况下,考虑选择查询中的连接条件作为分布列,这样Join任务可以下推到DN执行,DN之间的通信数据量可以减少。(4)一般不建议新增列作为分布列,特别是不建议新增列填充SEQUENCE的值作为分布列,因为SEQUENCE可能会造成性能瓶颈和不必要的维护成本。对于Hash分布表策略,如果分布列选择不当,可能会出现数据倾斜,查询时可能会出现一些DNI/O不足,从而影响整体查询性能。因此,采用Hash分表策略后,需要对表数据进行数据偏度检查,保证数据均匀分布在各个DN上。GaussDB提供了一个视图pgxc_get_table_skewness,可以在每个DN中查询数据库中所有schema下表的分布和偏斜率。虽然可以通过schemaname和tablename查询指定表的倾斜度,但是这个视图查询时间较长,只适用于数据量小的表(小于10W),尤其不建议查询的数据倾斜度所有表不添加条件。该视图各字段说明如下:此外,您还可以使用函数table_skewness()和table_distribution()查询指定表的数据倾斜度。使用table_skewness()时,如果没有指定具体字段,则默认查询当前分布列的数据偏斜度,该函数可用于评估表中其他字段的分布偏斜度。同样,当表的数据量很大时,这两个函数查询的时间也比较长。因此,对于数据量较大的表,一般使用如下语句查询其数据偏度:selectxc_node_id,count(1)fromtablenamegroupbyxc_node_idorderbyxc_node_iddesc;如果需要查询数据库中的偏斜表,除了使用上述视图pgxc_get_table_skewness外,还可以通过查看每个DN实例的数据存储目录和数据文件的大小来查找偏斜表,这也是实际应用中常用的方法。具体方法和步骤如下:(1)在所有节点上执行df-h,查看各个DN数据目录的利用率是否接近,找到利用率明显较大的磁盘目录。(2)通过cm_ctlquery–Cvd确认磁盘节点对应的DN实例(如果上一步slave磁盘占用过大,需要查看standby实例对应的primary实例的磁盘占用情况),以及确认DN实例端口号。DN实例的端口号可以通过以下方式查询:select*frompgxc_node;或catDN实例数据目录/postgresql.conf|grepPort(3)进入实例基目录,执行du-ak|排序-nr|more查找文件大小为1GB,且文件前缀编号ID相同的文件,查找相同文件数最多的文件,记录其ID值和所在文件目录的ID值。(4)通过gsql连接DN实例,通过文件目录ID确认该表所属的数据库。selectoid,*frompg_databasewhereoid='1642599';(5)切换到数据库,通过文件ID确认表名,执行如下SQL:selectrelnamefrompg_classwhereelfilenode=3308672;(6)根据表名进一步确认表的schema,执行如下SQL:SELECTn.nspnameas"Schema",c.relnameas"Name"FROMpg_catalog.pg_classcLEFTJOINpg_catalog.pg_namespacenONn.oid=c.relnamespaceWHERErelname='insured';(7)通过gsql连接CN实例,最后通过table_skewness()函数验证确认。
