开发者社区> 问答> 正文

什么是表结构优化?



7.3 表结构优化



分区列选择


基本原理分析型数据库的表一级分区采用hash分区,可指定任意一列(不支持多列)作为分区列,然后采用以下标准CRC算法,计算出CRC值,并将CRC值模分区数,得出每条记录的分区号。空值的hash值与字符串”-1”相同。<PRE prettyprinted? linenums>

  1. private static long getCRC32(String value) {
  2. Checksum checksum = new CRC32();
  3.         byte[] bytes = value.getBytes();
  4.         checksum.update(bytes, 0, bytes.length);
  5.         return checksum.getValue();
  6.     }

分析型数据库的调度模块会将同一个表组下所有表的相同分区分配在同一个计算节点上。好处在于,当出现多表使用分区列join时,单计算节点内部直接计算,避免跨机计算。
分区列选择依据(按优先级高低排序):
  1. 如果有多个事实表(不包括维度表)进行join,选择参与join的列作为分区列。

如果有多列join怎么办?可根据查询重要程度或者查询性能要求(例如某SQL的查询频率特别高),选择某列作为分区列,这样可以保证基于分区列join的查询性能具有较好的性能。

  1. 选择group by 或distinct 包含的列作为分区列。

  2. 选择值分布均匀的列,不要选择分区倾斜的列作为分区列。

  3. 常用SQL包含某列的等值或in查询条件,选择该列作为分区列。

例如:
select * from table where id=123 and ….;

select * from table where user in(1, 2,3);

一级分区个数


基本原理
分析型数据库的COMPUTENODE Local/Merge计算引擎(大部分查询主要的计算引擎),会在每个分区并行计算,每个分区计算使用一个线程,分区计算结果汇总到FRONTNODE。因此分区数过小,会导致并发低,单查询RT时间长。而如果分区数过多,会导致计算结果数过多,增加FRONTNODE压力;同时由于分区数过大,更容易产生长尾效应。因此需要根据资源配置和查询特点,选择合适的分区数。
一级分区个数选择依据
注意:一级分区数不可修改。如需修改,必须删表重建。
  • 参快速join的多个事实表分区数必须相同。
  • 单分区的数据记录数建议为300万条到2000万之间。如果为二级分区,保证每个一级分区下的二级分区的记录数为300万条到2000万条之间。
  • 分区数应该大于ECU数量 X 6,同时需要考虑到将来扩容。例如:某DB为8个C1,则分区数需要大于8*6=48。
  • 单表一级分区数最大值为256。在某些极其特殊的环境中,可能最大值为512。
  • 单计算节点的分区数(包括二级分区)不能超过1万。


二级分区表适用场景以及二级分区保留个数设置


基本原理
二级分区主要是解决数据按固定时间(例如,天,周,月)增量导入,同时需要保留历史数据设计的。每个一级分区下会包含多个二级分区,其中每个二级分区的分区列值(通常为日期)相同,并作为一个完整的索引构建单元(每次导入产生一个二级分区)。
在执行查询过程,计算引擎能够自动根据查询条件,筛选出满足的二级分级,然后对每个符合条件的二级分区执行计算。
如果二级分区过多,由于每个二级分区作为独立查询单元,导致多次索引查询,性能下降;同时由于每个二级分区有独立的meta,因此会占用更大内存。如果二级分区较少的话,用户导入频率会降低,会影响数据的实时性。因此用户需要根据实际情况综合评估合理的二级分区更新间隔,以及保留个数。
最佳实践
单表二级分区数小于等于90,同时每个计算节点上总二级分区个数不超过1万个。每个一级分区下的二级分区包含的数据条数在300万到2000万之间。

聚集列的选择和设置


基本原理
分析型数据库数据存储支持按一列或多列排序(先按第一列排序,第一列相同情况下,使用第二列排序),保证该列值相同或相近的数据在磁盘同一位置。它的好处是,当以聚集列为查询条件时,查询结果保存在磁盘相同位置,可以减少IO次数。由于主聚集列只有一列,因此需要最合适的列作为主聚集列。
聚集列选择依据
  • 主要或大多数查询条件包括这一列,且该条件具有较高的筛选率。
  • Join 等值条件列(通常为一级分区列)作为聚集列。


列类型选择


基本原理AnalyticDB处理数值类型的性能远好于处理字符串类型。原因在于:
  • 值类型定长,占用内存少,存储空间小;
  • 数值类型计算更快,尤其是join时;

因此,强烈建议用户尽可能使用数值类型,减少使用字符串类型。
常见将字符串转换为数值类型方法:
  • 包含字符前缀或后缀,例如E12345,E12346等。可以直接去掉前缀或者将前缀映射为数字。
  • 该列只有少数几个值,例如国家名。可以对每个国家编码,每个国家对应一个唯一数字。

展开
收起
nicenelly 2017-10-26 15:48:16 2429 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
RowKey与索引设计:技巧与案例分析 立即下载
MySQL查询优化实战 立即下载
Phoenix 全局索引原理与实践 立即下载