分区与分桶概述
分区与分桶秉承着"大而化小,分而治之"的目标,目的都是为了便于查询,提高查询的效率。
分区的定义: 对数据进行水平切分,水平切分之后数据是完全物理隔离的,每个分区即为一个物理文件夹。
比如一个网站每天的埋点行为日志数据量比较大,在查询时进行全表扫描耗费的资源非常多。那在这个情况大数据体量下,可以按照每天日期对数据表进行分区,不同日期的数据存放在不同的分区下,在查询时只要指定分区字段的值就可以直接从该分区查找。
分桶的定义: 对数据进行垂直切分,各个分桶相互独立,每个分桶即为一个文件。
比如我们按照name列分为4个桶,就是对name列值的hash值对4取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件、取模为3的数据存放到一个文件。
从上面可见,分区注重粗粒度,而分桶注重细粒度。同时需要注意的是这存在一定的担忧:分区容易造成数据倾斜。
今天主要讲讲,Doris分区与分桶。
Doris支持两级分区存储, 第一层为 range 分区,也可支持list方式, 第二层为 hash分桶。
Drois分区
注意点
(1)分区列必须为key列。
(2)分区列可以指定一列或多列。
(3)不论分区列是什么类型,在写分区值时,都需要加双引号。
(4)add partition添加分区,可以为该分区单独指定桶的数量。
Range 分区
通过 values less than (xxx) 仅指定上界,系统会将前一个分区的上界作为该分区的下界,生成一个左闭右开的区间。
同 Range Partition,当导入数据值在分区范围外,则不会被导入。
PARTITION BY RANGE (`dt`) ( PARTITION p_20220501 VALUES LESS THAN ("2022-05-01"), PARTITION p_20220502 VALUES LESS THAN ("2022-05-02"), PARTITION p_20220503 VALUES LESS THAN ("2022-05-03"), PARTITION p_20220504 VALUES LESS THAN ("2022-05-04") )
List 分区
通过 VALUES IN (xxx) 来指定每个分区包含的枚举值,分区值为枚举值。只有当数据为目标分区枚举值其中之一时,才可以命中分区。
现List Partition 的分区列必须为 NOT NULL 列
PARTITION BY RANGE (`city_code`) ( PARTITION `p_city` VALUES IN ("1001", "1002", "1003") )
多列分区
PARTITION BY LIST(`id`, `city_code`) ( PARTITION `p_id_city` VALUES IN (("1", "1000"), ("1", "1001")) )
动态分区
表按date或datetime类型字段进行分区,对于新的数据,需要我们手动添加分区,和删除旧的分区,自动的总比手动的更加方便些。
PARTITION BY RANGE(dt)() PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "DAY", "dynamic_partition.end" = "3", "dynamic_partition.prefix" = "p", "replication_num" = "1" );
key | 说明 |
dynamic_partition.enable | 是否开启动态分区 |
dynamic_partition.time_unit | 区时间单位可以是hour、day、week、month。(yyyyMMddHH) |
dynamic_partition.start | 动态分区的起始偏移量,分区范围在此偏移之前的分区将会被删除,默认不删 |
dynamic_partition.end | 动态分区的结束偏移量,以当前为基准,提前创建对应范围的分区 |
dynamic_partition.prefix | 分区名前缀 |
以当前天(20220504)为基准,会提前创建三天的分区(20220505,20220506,20220507)
其他操作
关掉动态分区
ALTER TABLE xxx SET ("dynamic_partition.enable" = "false")
删除分区
ALTER TABLE xxx DROP PARTITION p_20220504;
新建分区
ALTER TABLE xxx ADD PARTITION p_20220505 VALUES [('2022-05-05'), ('2022-05-06'));
查看分区
show partitions from xxx
Drois 分桶
DISTRIBUTED BY HASH(id) BUCKETS 10
注意点
(1)分桶列可以是多列,但必须为 Key 列。
- 分桶列少:对应的查询可以仅触发分桶扫描区域就少,查询之间的IO影响较小,适合高并发。
- 分桶列多,数据分布更均匀,查询有可能会触发所有分桶同时扫描,查询的吞吐会增加,适合大吞吐低并发的查询。
(2)分桶列可以和分区列相同或不同。