• 沒有找到結果。

2.1.1 学习“教程:调优表设计”

进行数据库设计时,表设计上的一些关键项将严重影响后续整库的查询性能。表设计 对数据存储也有影响:好的表设计能够减少I/O操作及最小化内存使用,进而提升查询 性能。

教程指引指导您逐步完成选择排序键、分配方式和压缩编码的过程,并介绍如何比较 优化前后的系统性能。

下面各节总结最重要的表设计关键考虑点并给出优秀的实践建议。

2.1.2 选择存储模型

进行数据库设计时,表设计上的一些关键项将严重影响后续整库的查询性能。表设计 对数据存储也有影响:好的表设计能够减少I/O操作及最小化内存使用,进而提升查询 性能。

表的存储模型选择是表定义的第一步。业务属性是表的存储模型的决定性因素,依据 下面表格选择适合当前业务的存储模型。

存储模型 适用场景

行存 点查询(返回记录少,基于索引的简单查询)。

增删改比较多的场景。

列存 统计分析类查询 (group , join多的场景)。

2.1.3 选择分布方式

复制表(Replication)方式将表中的全量数据在集群的每一个DN实例上保留一份。主 要适用于记录集较小的表。这种存储方式的优点是每个DN上都有此表的全量数据,在 join操作中可以避免数据重分布操作,从而减小网络开销,同时减少了plan

segment(每个plan segment都会起对应的线程);缺点是每个DN都保留了表的完整数 据,造成数据的冗余。一般情况下只有较小的维度表才会定义为Replication表。

哈希(Hash)表将表中某一个或几个字段进行hash运算后,生成对应的hash值,根据 DN实例与哈希值的映射关系获得该元组的目标存储位置。对于Hash分布表,在读/写 数据时可以利用各个节点的IO资源,大大提升表的读/写速度。一般情况下大表定义为 Hash表。

策略 描述 适用场景

Hash 表数据通过hash方式散列到集群中的所

有DN实例上。 数据量较大的事实表。

Replication 集群中每一个DN实例上都有一份全量表 数据。

小表、维度表。

如图2-1所示,复制表如图中的表T1,哈希表如图中的表T2。

2-1 复制表和哈希表

2.1.4 选择分布列

Hash分布表的分布列选取至关重要,需要满足以下原则:

1. 列值应比较离散,以便数据能够均匀分布到各个DN。例如,考虑选择表的主键为 分布列,如在人员信息表中选择身份证号码为分布列。

2. 在满足第一条原则的情况下尽量不要选取存在常量filter的列。例如,表dwcjk相 关的部分查询中出现dwcjk的列zqdh存在常量的约束(例如zqdh=’000001’),那 么就应当尽量不用zqdh做分布列。

3. 在满足前两条原则的情况,考虑选择查询中的连接条件为分布列,以便Join任务能 够下推到DN中执行,且减少DN之间的通信数据量。

对于Hash分表策略,如果分布列选择不当,可能导致数据倾斜,查询时出现部分 DN的I/O短板,从而影响整体查询性能。因此在采用Hash分表策略之后需对表的 数据进行数据倾斜性检查,以确保数据在各个DN上是均匀分布的。可以使用以下 SQL检查数据倾斜性

select

xc_node_id, count(1) from tablename group by xc_node_id order by xc_node_id desc;

其中xc_node_id对应DN,一般来说,不同DN的数据量相差5%以上即可视为倾 斜,如果相差10%以上就必须要调整分布列。

4. 一般不建议用户新增一列专门用作分布列,尤其不建议用户新增一列,然后用 SEQUENCE的值来填充做为分布列。因为SEQUENCE可能会带来性能瓶颈和不必 要的维护成本。

GaussDB(DWS)支持多分布列特性,可以更好地满足数据分布的均匀性要求。

2.1.5 使用分区表

分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储。这张逻辑上的表 称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是 存储在分区上的。分区表和普通表相比具有以下优点:

1. 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索效率。

2. 增强可用性:如果分区表的某个分区出现故障,表在其他分区的数据仍然可用。

3. 方便维护:如果分区表的某个分区出现故障,需要修复数据,只修复该分区即 可。

GaussDB(DWS)支持的分区表为范围分区表。

范围分区表:将数据基于范围映射到每一个分区。这个范围是由创建分区表时指定的 分区键决定的。分区键经常采用日期,例如将销售数据按照月份进行分区。

2.1.6 使用局部聚簇

局部聚簇(Partial Cluster Key)是列存下的一种技术。这种技术可以通过min/max稀 疏索引较快的实现基表扫描的filter过滤。Partial Cluster Key可以指定多列,但是一般 不建议超过2列。Partial Cluster Key的选取原则:

1. 受基表中的简单表达式约束。这种约束一般形如col op const,其中col为列名,

op为操作符 =、>、>=、<=、<,const为常量值。

2. 尽量采用选择度比较高(过滤掉更多数据)的简单表达式中的列。

3. 尽量把选择度比较低的约束col放在Partial Cluster Key中的前面。

4. 尽量把枚举类型的列放在Partial Cluster Key中的前面。

2.1.7 选择数据类型

高效数据类型,主要包括以下三方面:

1. 尽量使用执行效率比较高的数据类型

一般来说整型数据运算(包括=、>、<、≧、≦、≠等常规的比较运算,以及 group by)的效率比字符串、浮点数要高。比如某客户场景中对列存表进行点查 询,filter条件在一个numeric列上,执行时间为10+s;修改numeric为int类型之 后,执行时间缩短为1.8s左右。

2. 尽量使用短字段的数据类型

长度较短的数据类型不仅可以减小数据文件的大小,提升IO性能;同时也可以减 小相关计算时的内存消耗,提升计算性能。比如对于整型数据,如果可以用 smallint就尽量不用int,如果可以用int就尽量不用bigint。

3. 使用一致的数据类型

表关联列尽量使用相同的数据类型。如果表关联列数据类型不同,数据库必须动 态地转化为相同的数据类型进行比较,这种转换会带来一定的性能开销。