
Doris Rollup(学习笔记)
ROLLUP 在多维分析中是“上卷”的意思,即将数据按某种指定的粒度进行进一步聚合。
之前的聚合模型:
1.求每个城市的每个用户的每天的总销售额
select
user_id,city,date,
sum(sum_cost) as sum_cost
from t
group by user_id,city,date
2.求每个用户、每个城市的总消费额
select
user_id,city,
sum(sum_cost) as sum_cost
from t
group by user_id,city
3.求每个用户的总消费额
select
user_id,
sum(sum_cost) as sum_cost
from t
group by user_id
基本概念
通过建表语句创建出来的表称为 Base 表(Base Table,基表)
在 Base 表之上,我们可以创建任意多个 ROLLUP 表。这些 ROLLUP 的数据是基于 Base 表产生的,并且在物理上是独立存储的。
Rollup表的好处:
1.和基表共用一个表名,doris会根据具体的查询逻辑选择合适的数据源(合适的表)来计算结果
2.对于基表中数据的增删改,rollup表会自动更新同步
Aggregate 模型中的 ROLLUP
查看下之前建得一张表:
示例1:查看某个用户的总消费
添加一个rollup
alter table aggregate表名 add rollup "rollup表的表名" (user_id,city,date,cost);
添加三张rollup表
alter table ex_user add rollup rollup_ucd_cost(user_id,city,date,cost);
alter table ex_user add rollup rollup_u_cost(user_id,cost);
alter table ex_user add rollup rollup_cd_cost(city,date,cost);
添加这个rollup表,需要消耗时间,所以执行完之后需要等一会儿,再使用desc 查看表结构。
alter table ex_user drop rollup rollup_u_cost;
alter table ex_user drop rollup rollup_cd_cost;
--如果是replace聚合类型得value,需要指定所有得key
-- alter table ex_user add rollup rollup_cd_visit(city,date,last_visit_date);
-- ERROR 1105 (HY000): errCode = 2, detailMessage = Rollup should contains
-- all keys if there is a REPLACE value
--添加完成之后可以show一下,看看底层得rollup有没有执行完成,这里只是记录没有实际的用处
SHOW ALTER TABLE ROLLUP;
再次查看该表得详细信息后发现,多了一个IndexName为rollup_ucd_cost
Doris 会自动命中这个 ROLLUP 表,从而只需扫描极少的数据量,即可完成这次聚合查询。
explain SELECT user_id, sum(cost) FROM ex_user GROUP BY user_id;
示例 2:获得不同城市,不同年龄段用户的总消费、最长和最短页面驻留时间
alter table ex_user add rollup rollup_city(city,age,cost,max_dwell_time,min_dwell_time);
-- 当创建好了立即去查看得时候就会发现,他还没有开始
SHOW ALTER TABLE ROLLUP;
然后过会再去查询得时候,他就完成了,看他的状态即可
分别执行下面得三条语句,看看有什么不一样的??
explain SELECT city, age, sum(cost), max(max_dwell_time), min(min_dwell_time) FROM ex_user GROUP BY city, age;
explain SELECT city, sum(cost), max(max_dwell_time), min(min_dwell_time) FROM ex_user GROUP BY city;
explain SELECT city, age, sum(cost), min(min_dwell_time) FROM ex_user GROUP BY city, age;
很显然得发现,维度是city,或者age,或者他们组合得时候,都是可以命中这个rollup得,相对来说效率会高很多
Unique 模型中的 ROLLUP
unique模型示例表
drop table if exists test.user;
CREATE TABLE IF NOT EXISTS test.user
(
`user_id` LARGEINT NOT NULL COMMENT "用户 id",
`username` VARCHAR(50) NOT NULL COMMENT "用户昵称",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`phone` LARGEINT COMMENT "用户电话",
`address` VARCHAR(500) COMMENT "用户地址",
`register_time` DATETIME COMMENT "用户注册时间" )
UNIQUE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
PROPERTIES (
"replication_num" = "1"
);
插入语句
insert into test.user values
(10000,'zss','北京',18,0,12345678910,'北京朝阳区 ','2017-10-01 07:00:00'),
(10000,'zss','北京',18,0,12345678910,'北京朝阳区 ','2017-10-01 08:00:00'),
(10001,'lss','北京',20,0,12345678910,'北京海淀区','2017-11-15 06:10:20');
在unique模型中做rollup表,rollup的key必须延用base表中所有的key,不同的是value可以随意指定
alter table user add rollup rollup_username_id(username,user_id,age);
这里我没尝试成功不知道为什么,但是好像没什么意义。
试想一下:
如果不沿用base表中所有的key,只针对上面的user_id进行rollup,那么他的age值取20还是19呢?好像也就不确定了,毕竟底层的aggregationType 用的是replace,到底谁替换谁就不确定了
Duplicate 模型中的 ROLLUP
因为 Duplicate 模型没有聚合的语意。
所以该模型中的 ROLLUP,已经失去了“上卷” 这一层含义。
而仅仅是作为调整列顺序,以命中前缀索引的作用。
下面详细介绍前缀索引,以及如何使用 ROLLUP 改变前缀索引,以获得更好的查询效率。
ROLLUP 调整前缀索引(新增一套前缀索引)
因为建表时已经指定了列顺序,所以一个表只有一种前缀索引。
这对于使用其他不能命中前缀索引的列作为条件进行的查询来说,效率上可能无法满足需求。
因此,我们可以通过创建 ROLLUP 来人为的调整列顺序。
Base 表结构如下:
我们可以在此基础上创建一个 ROLLUP 表:
为什么说rollup 可以调整列值的顺序?
rollup 是一个真实的表,它是base表的一种复制。
我有什么动力调整这个顺序?
因为我们以前学习过一个优化索引,叫做前缀索引法则,按照书写顺序来匹配,匹配越高,效率越高。
可以看到,ROLLUP 和 Base 表的列完全一样,只是将 user_id 和 age 的顺序调换了。
那么当我们进行如下查询时:
SELECT * FROM table where age=20 and message LIKE "%error%";
会优先选择 ROLLUP 表,因为 ROLLUP 的前缀索引匹配度更高。
示例:针对上面的log_detail这张基表添加两个rollup表
按照type 和error_code 进行建前缀索引
alter table log_detail add rollup rollup_tec(type,error_code,timestamp,error_msg,op_id,op_time);
--删除
--alter table log_detail drop rolluprollup_tec
按照op_id和error_code 进行建前缀索引
alter table log_detail add rollup rollup_oec(op_id,error_code,timestamp,type,error_msg,op_time);
查看表中基表和rollup表。
示例:看如下sql会命中哪一张表。
explain select * from log_detail where type = 1; --rollup_tec
explain select * from log_detail where type = 1 and error_code = 404; --rollup_tec
explain select * from log_detail where op_id = 101 ; -- rollup_oec
explain select * from log_detail where op_id = 101 and error_code = 404; -- rollup_oec
explain select * from log_detail where timestamp = '2017-10-01 08:00:05' ; --log_detail
explain select * from log_detail where timestamp = '2017-10-01 08:00:05' and type = 1;--log_detail
ROLLUP使用说明
1.ROLLUP 是附属于 Base 表的,用户可以在 Base 表的基础上,创建或删除 ROLLUP,但是不能在查询中显式的指定查询某 ROLLUP。是否命中 ROLLUP 完全由 Doris 系统自动决定
2.ROLLUP 的数据是独立物理存储的。
因此,创建的 ROLLUP 越多,占用的磁盘空间也就越大。
同时对导入速度也会有影响,但是不会降低查询效率(只会更好)。
3.ROLLUP 的数据更新与 Base 表是完全同步的。
用户无需关心这个问题。
4.在聚合模型中,ROLLUP 中列的聚合类型,与 Base 表完全相同。
在创建 ROLLUP 无需指定,也不能修改。
5.可以通过 EXPLAIN your_sql;
命令获得查询执行计划,在执行计划中,查看是否命中 ROLLUP。
6.可以通过 DESC tbl_name ALL;
语句显示 Base 表和所有已创建完成的 ROLLUP
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

