Doris分区与分桶(八)

接上篇----------Doris 建表示例

Doris 支持两层的数据划分。第一层是 Partition,支持 Range 和 List 的划分方式。第二层是 Bucket(Tablet),仅支持 Hash 的划分方式。

也可以仅使用一层分区。使用一层分区时,只支持 Bucket 划分。

Partition
  • Partition 列可以指定一列或多列。分区类必须为 KEY 列。

  • 不论分区列是什么类型,在写分区值时,都需要加双引号。

  • 分区数量理论上没有上限。

  • 当不使用 Partition 建表时,系统会自动生成一个和表名同名的,全值范围的Partition。该 Partition 对用户不可见,并且不可删改。

Range 分区

分区列通常为时间列,以方便的管理新旧数据。不可添加范围重叠的分区。 Partition 指定范围的方式

VALUES LESS THAN (...) 仅指定上界,系统会将前一个分区的上界作为该分区的下界,生成一个左闭右开的区间。分区的删除不会改变已存在分区的范围。删除分区可能出现空洞。

VALUES [...) 指定同时指定上下界,生成一个左闭右开的区间。

通过 VALUES [...) 同时指定上下界比较容易理解。这里举例说明,当使用 VALUES LESS THAN (...) 语句进行分区的增删操作时,分区范围的变化情况:

(1)如上 expamle_range_tbl 示例,当建表完成后,会自动生成如下 3 个分区:

复制代码
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201703: [2017-03-01, 2017-04-01)

(2)增加一个分区 p201705 VALUES LESS THAN ("2017-06-01"),分区结果如下:

复制代码
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201703: [2017-03-01, 2017-04-01)
p201705: [2017-04-01, 2017-06-01)

(3)此时删除分区 p201703,则分区结果如下:

复制代码
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)

注意到 p201702 和 p201705 的分区范围并没有发生变化,而这两个分区之间,出现了一个空洞:[2017-03-01, 2017-04-01)。即如果导入的数据范围在这个空洞范围内,是无法导入的。

(4)继续删除分区 p201702,分区结果如下:

复制代码
p201701: [MIN_VALUE, 2017-02-01)
p201705: [2017-04-01, 2017-06-01)

空洞范围变为:[2017-02-01, 2017-04-01)

(5)现在增加一个分区 p201702new VALUES LESS THAN ("2017-03-01"),分区结果如下:

复制代码
p201701: [MIN_VALUE, 2017-02-01)
p201702new: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)

可以看到空洞范围缩小为:[2017-03-01, 2017-04-01)

(6)现在删除分区 p201701,并添加分区 p201612 VALUES LESS THAN ("2017-01-01"),分区结果如下:

复制代码
p201612: [MIN_VALUE, 2017-01-01)
p201702new: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)

即出现了一个新的空洞:[2017-01-01, 2017-02-01)

List 分区

分 区 列支 持 BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DATE, DATETIME, CHAR, VARCHAR 数据类型,分区值为枚举值。只有当数据为目标分区枚举值

其中之一时,才可以命中分区。不可添加范围重叠的分区。

Partition 支持通过 VALUES IN (...) 来指定每个分区包含的枚举值。下面通过示例说明,进行分区的增删操作时,分区的变化。

(1)如上 example_list_tbl 示例,当建表完成后,会自动生成如下 3 个分区:

复制代码
p_cn: ("Beijing", "Shanghai", "Hong Kong")
p_usa: ("New York", "San Francisco")
p_jp: ("Tokyo")

(2)增加一个分区 p_uk VALUES IN ("London"),分区结果如下:

复制代码
p_cn: ("Beijing", "Shanghai", "Hong Kong")
p_usa: ("New York", "San Francisco")
p_jp: ("Tokyo")
p_uk: ("London")

(3)删除分区 p_jp,分区结果如下:

复制代码
p_cn: ("Beijing", "Shanghai", "Hong Kong")
p_usa: ("New York", "San Francisco")
p_uk: ("London")

Bucket

(1)如果使用了 Partition,则 DISTRIBUTED ... 语句描述的是数据在各个分区内的划分规则。如果不使用 Partition,则描述的是对整个表的数据的划分规则。

(2)分桶列可以是多列,但必须为 Key 列。分桶列可以和 Partition 列相同或不同。

(3)分桶列的选择,是在 查询吞吐 和 查询并发 之间的一种权衡:

  • ① 如果选择多个分桶列,则数据分布更均匀。如果一个查询条件不包含所有分桶列的等值条件,那么该查询会触发所有分桶同时扫描,这样查询的吞吐会增加,单个查询的延迟随之降低。这个方式适合大吞吐低并发的查询场景。

  • ② 如果仅选择一个或少数分桶列,则对应的点查询可以仅触发一个分桶扫描。此时,当多个点查询并发时,这些查询有较大的概率分别触发不同的分桶扫描,各个查询之间的 IO 影响较小(尤其当不同桶分布在不同磁盘上时),所以这种方式适合高并发的点查询场景。

(4)分桶的数量理论上没有上限。

使用复合分区的场景

以下场景推荐使用复合分区

(1)有时间维度或类似带有有序值的维度,可以以这类维度列作为分区列。分区粒度可以根据导入频次、分区数据量等进行评估。

(2)历史数据删除需求:如有删除历史数据的需求(比如仅保留最近 N 天的数据)。使用复合分区,可以通过删除历史分区来达到目的。也可以通过在指定分区内发送 DELETE 语句进行数据删除。

(3)解决数据倾斜问题:每个分区可以单独指定分桶数量。如按天分区,当每天的数据量差异很大时,可以通过指定分区的分桶数,合理划分不同分区的数据,分桶列建议选择区分度大的列。

多列分区

Doris 支持指定多列作为分区列,示例如下:

1)Range 分区
复制代码
PARTITION BY RANGE(`date`, `id`)
(
 PARTITION `p201701_1000` VALUES LESS THAN ("2017-02-01", "1000"),
 PARTITION `p201702_2000` VALUES LESS THAN ("2017-03-01", "2000"),
 PARTITION `p201703_all` VALUES LESS THAN ("2017-04-01")
)

指定 date(DATE 类型) 和 id(INT 类型) 作为分区列。以上示例最终得到的分区如下:

复制代码
p201701_1000: [(MIN_VALUE, MIN_VALUE), ("2017-02-01", "1000") )
p201702_2000: [("2017-02-01", "1000"), ("2017-03-01", "2000") )
p201703_all: [("2017-03-01", "2000"), ("2017-04-01", MIN_VALUE))

注意,最后一个分区用户缺省只指定了 date 列的分区值,所以 id 列的分区值会默认填充 MIN_VALUE。当用户插入数据时,分区列值会按照顺序依次比较,最终得到对应的分区。举例如下:

复制代码
数据 --> 分区
2017-01-01, 200 --> p201701_1000
2017-01-01, 2000 --> p201701_1000
2017-02-01, 100 --> p201701_1000
2017-02-01, 2000 --> p201702_2000
2017-02-15, 5000 --> p201702_2000
2017-03-01, 2000 --> p201703_all
2017-03-10, 1 --> p201703_all
2017-04-01, 1000 --> 无法导入
2017-05-01, 1000 --> 无法导入
2)List 分区
复制代码
PARTITION BY LIST(`id`, `city`)
(
 PARTITION `p1_city` VALUES IN (("1", "Beijing"), ("1", "Shanghai")),
 PARTITION `p2_city` VALUES IN (("2", "Beijing"), ("2", "Shanghai")),
 PARTITION `p3_city` VALUES IN (("3", "Beijing"), ("3", "Shanghai"))
)

指定 id(INT 类型) 和 city(VARCHAR 类型) 作为分区列。最终得到的分区如下:

复制代码
p1_city: [("1", "Beijing"), ("1", "Shanghai")]
p2_city: [("2", "Beijing"), ("2", "Shanghai")]
p3_city: [("3", "Beijing"), ("3", "Shanghai")]

当用户插入数据时,分区列值会按照顺序依次比较,最终得到对应的分区。举例如下:

复制代码
数据 ---> 分区
1, Beijing ---> p1_city
1, Shanghai ---> p1_city
2, Shanghai ---> p2_city
3, Beijing ---> p3_city
1, Tianjin ---> 无法导入
4, Beijing ---> 无法导入

接下篇----------Doris的PROPERTIES与ENGINE

相关推荐
K_i1347 小时前
Hadoop 集群自动化运维实战
运维·hadoop·自动化
Q264336502310 小时前
【有源码】基于Python与Spark的火锅店数据可视化分析系统-基于机器学习的火锅店综合竞争力评估与可视化分析-基于用户画像聚类的火锅店市场细分与可视化研究
大数据·hadoop·python·机器学习·数据分析·spark·毕业设计
顧棟1 天前
【Yarn实战】Yarn 2.9.1滚动升级到3.4.1调研与实践验证
hadoop·yarn
D明明就是我1 天前
Hive 拉链表
数据仓库·hive·hadoop
嘉禾望岗5031 天前
hive join优化和数据倾斜处理
数据仓库·hive·hadoop
yumgpkpm1 天前
华为鲲鹏 Aarch64 环境下多 Oracle 数据库汇聚操作指南 CMP(类 Cloudera CDP 7.3)
大数据·hive·hadoop·elasticsearch·zookeeper·big data·cloudera
忧郁火龙果1 天前
六、Hive的基本使用
数据仓库·hive·hadoop
忧郁火龙果1 天前
五、安装配置hive
数据仓库·hive·hadoop
chad__chang2 天前
dolphinscheduler安装过程
hive·hadoop
ajax_beijing2 天前
hadoop的三副本数据冗余策略
大数据·hadoop·分布式