一. 基本概念
在 Doris 中,我们将用户通过建表语句创建出来的表称为 Base 表(Base Table)。Base 表中保存着按用户建表语句指定的方式存储的基础数据。
在 Base 表之上,我们可以创建任意多个 ROLLUP 表。这些 ROLLUP 的数据是基于 Base 表产生的,并且在物理上是独立存储的。
ROLLUP 表的基本作用,在于在 Base 表的基础上,获得更粗粒度的聚合数据。
下面我们用示例详细说明在不同数据模型中的 ROLLUP 表及其作用。
二. Aggregate 和 Uniq 模型中的 ROLLUP
因为 Uniq 只是 Aggregate 模型的一个特例,所以这里我们不加以区别。
2.1 测试数据准备
MySQL端数据准备:
MySQL测试数据准备
数据导入doris:
CREATE TABLE ods_fact_sale_doris
(
id BIGINT DEFAULT '0',
sale_date varchar(100),
prod_name varchar(32),
sale_nums BIGINT SUM
) ENGINE=OLAP
AGGREGATE KEY(id,sale_date,prod_name)
DISTRIBUTED BY HASH(sale_date) BUCKETS 10
PROPERTIES("replication_num" = "3");
LOAD LABEL table3_20211213_1
(
DATA INFILE("hdfs://10.31.1.123:8020/user/hive/warehouse/test.db/ods_fact_sale_orc/*")
INTO TABLE ods_fact_sale_doris
FORMAT AS 'orc'
(id,sale_date,prod_name,sale_nums)
SET
(
sale_date=sale_date,
prod_name=prod_name,
id = id,
sale_nums=sale_nums
)
)
WITH BROKER broker_name
(
"username"="doris_user",
"password"="abc123"
)
PROPERTIES
(
"timeout"="3600",
"max_filter_ratio"="1"
);
SHOW LOAD WHERE LABEL = "table3_20211213_1"\G
2.2 获取每一天的销售额
2.2.1 直接写sql
select sale_date,sum(sale_nums) as all_nums
from ods_fact_sale_doris
group by sale_date;
最终花了差不多38秒。
image.png
2.2.2 先使用rollup聚合再查询
ALTER TABLE ods_fact_sale_doris ADD ROLLUP Rollup5(sale_date,sale_nums);
SHOW ALTER TABLE ROLLUP;
image.png
可以看到,ROLLUP 中仅保留了每个 sale_date,在 sale_nums 列上的 SUM 的结果。那么当我们进行如下查询时:
select sale_date,sum(sale_nums) as all_nums
from ods_fact_sale_doris
group by sale_date;
Doris 会自动命中这个 ROLLUP 表,从而只需扫描极少的数据量,即可完成这次聚合查询。
image.png
三. ROLLUP 的几点说明
-
ROLLUP 最根本的作用是提高某些查询的查询效率(无论是通过聚合来减少数据量,还是修改列顺序以匹配前缀索引)。因此 ROLLUP 的含义已经超出了 “上卷” 的范围。这也是为什么我们在源代码中,将其命名为 Materialized Index(物化索引)的原因。
-
ROLLUP 是附属于 Base 表的,可以看做是 Base 表的一种辅助数据结构。用户可以在 Base 表的基础上,创建或删除 ROLLUP,但是不能在查询中显式的指定查询某 ROLLUP。是否命中 ROLLUP 完全由 Doris 系统自动决定。
-
ROLLUP 的数据是独立物理存储的。因此,创建的 ROLLUP 越多,占用的磁盘空间也就越大。同时对导入速度也会有影响(导入的ETL阶段会自动产生所有 ROLLUP 的数据),但是不会降低查询效率(只会更好)。
-
ROLLUP 的数据更新与 Base 表示完全同步的。用户无需关心这个问题。
-
ROLLUP 中列的聚合方式,与 Base 表完全相同。在创建 ROLLUP 无需指定,也不能修改。
-
查询能否命中 ROLLUP 的一个必要条件(非充分条件)是,查询所涉及的所有列(包括 select list 和 where 中的查询条件列等)都存在于该 ROLLUP 的列中。否则,查询只能命中 Base 表。
-
某些类型的查询(如 count(*))在任何条件下,都无法命中 ROLLUP。
-
可以通过 EXPLAIN your_sql; 命令获得查询执行计划,在执行计划中,查看是否命中 ROLLUP。
-
可以通过 DESC tbl_name ALL; 语句显示 Base 表和所有已创建完成的 ROLLUP。
网友评论