ROLLUP 在多维分析中是“上卷”的意思,即将数据按某种指定的粒度进行进一步聚合。
用户id | 数据插入时间 | 城市 | 年龄 | 性别 | 最后一次访问的时间 | 该用户的总消费额 | 该用户的最大停留时长 | 该用户的最小停留时长 |
10000 | 2017/10/2 | 北京 | 10 | 0 | 2017/10/02 08:00:00 | 65 | 15 | 2 |
10000 | 2017/10/2 | 北京 | 20 | 0 | 2017/10/02 08:00:00 | 65 | 15 | 2 |
10000 | 2017/10/2 | 北京 | 30 | 0 | 2017/10/02 08:00:00 | 65 | 15 | 2 |
10000 | 2017/10/1 | 上海 | 20 | 0 | 2017/10/01 08:00:00 | 100 | 122 | 2 |
10000 | 2017/10/2 | 上海 | 20 | 0 | 2017/10/02 08:00:00 | 30 | 30 | 2 |
10000 | 2017/10/3 | 上海 | 10 | 0 | 2017/10/03 08:00:00 | 55 | 33 | 2 |
10000 | 2017/10/4 | 上海 | 20 | 0 | 2017/10/04 08:00:00 | 65 | 15 | 2 |
10001 | 2017/10/1 | 上海 | 30 | 1 | 2017/10/01 17:05:45 | 20 | 22 | 22 |
10001 | 2017/10/2 | 上海 | 10 | 1 | 2017/10/01 17:05:45 | 10 | 123 | 22 |
10001 | 2017/10/2 | 天津 | 10 | 1 | 2017/10/01 17:05:45 | 18 | 2 | 22 |
10001 | 2017/10/1 | 上海 | 10 | 1 | 2017/10/01 17:05:45 | 10 | 123 | 22 |
10001 | 2017/10/1 | 天津 | 10 | 1 | 2017/10/01 17:05:45 | 18 | 2 | 22 |
10001 | 2017/10/1 | 天津 | 20 | 1 | 2017/10/01 17:05:45 | 28 | 45 | 22 |
10002 | 2017/10/1 | 天津 | 30 | 1 | 2017/10/01 17:05:45 | 35 | 11 | 22 |
10002 | 2017/10/2 | 天津 | 10 | 1 | 2017/10/01 08:00:00 | 20 | 23 | 2 |
10002 | 2017/10/2 | 北京 | 20 | 1 | 2017/10/03 17:05:45 | 35 | 11 | 22 |
10002 | 2017/10/1 | 天津 | 10 | 1 | 2017/10/01 08:00:00 | 20 | 23 | 2 |
10002 | 2017/10/3 | 北京 | 20 | 1 | 2017/10/03 17:05:45 | 35 | 11 | 22 |
10002 | 2017/10/3 | 北京 | 30 | 1 | 2017/10/03 08:00:00 | 20 | 23 | 2 |
1.求每个城市的每个用户的每天的总销售额
select
user_id,city,date,
sum(sum_cost) as sum_cost
from t
group by user_id,city,date
-- user_id date city sum_cost
10000 2017/10/2 北京 195
10000 2017/10/1 上海 100
10000 2017/10/2 上海 30
10000 2017/10/3 上海 55
10000 2017/10/4 上海 65
10001 2017/10/1 上海 30
10001 2017/10/2 上海 10
10001 2017/10/2 天津 18
10001 2017/10/1 天津 46
10002 2017/10/1 天津 55
10002 2017/10/3 北京 55
10002 2017/10/2 天津 20
10002 2017/10/2 北京 35
2.求每个用户、每个城市的总消费额
select
user_id,city,
sum(sum_cost) as sum_cost
from t
group by user_id,city
user_id city sum_cost
10000 北京 195
10000 上海 100
10001 上海 40
10001 天津 64
10002 天津 75
10002 北京 90
3.求每个用户的总消费额
select
user_id,
sum(sum_cost) as sum_cost
from t
group by user_id
user_id sum_cost
10000 295
10001 104
10002 165
通过建表语句创建出来的表称为 Base 表(Base Table,基表)
在 Base 表之上,我们可以创建任意多个 ROLLUP 表。这些 ROLLUP 的数据是基于 Base 表产生的,并且在物理上是独立存储的。
Rollup表的好处:
和基表共用一个表名,doris会根据具体的查询逻辑选择合适的数据源(合适的表)来计算结果
对于基表中数据的增删改,rollup表会自动更新同步
查看下之前建得一张表:
mysql> desc ex_user all;
示例1:查看某个用户的总消费
添加/删除roll up表
alter table aggregate表名 add rollup "rollup表的表名" (user_id,city,date,cost);
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);
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;
Doris 会自动命中这个 ROLLUP 表,从而只需扫描极少的数据量,即可完成这次聚合查询。
explain SELECT user_id, sum(cost) FROM ex_user GROUP BY user_id;
ROLLUP 调整前缀索引(新增一套前缀索引)
因为建表时已经指定了列顺序,所以一个表只有一种前缀索引。这对于使用其他不能命中前缀索引的列作为条件进行的查询来说,效率上可能无法满足需求。因此,我们可以通过创建 ROLLUP 来人为的调整列顺序。
Base 表结构如下:
ColumnName | Type |
user_id | BIGINT |
age | INT |
message | VARCHAR(100) |
max_dwell_time | DATETIME |
min_dwell_time | DATETIME |
我们可以在此基础上创建一个 ROLLUP 表:
ColumnName | Type |
age | INT |
user_id | BIGINT |
message | VARCHAR(100) |
max_dwell_time | DATETIME |
min_dwell_time | DATETIME |
可以看到,ROLLUP 和 Base 表的列完全一样,只是将 user_id 和 age 的顺序调换了。那么当我们进行如下查询时:
SELECT * FROM table where age=20 and message LIKE "%error%";
会优先选择 ROLLUP 表,因为 ROLLUP 的前缀索引匹配度更高。
ROLLUP使用说明
ROLLUP 是附属于 Base 表的,用户可以在 Base 表的基础上,创建或删除 ROLLUP,但是不能在查询中显式的指定查询某 ROLLUP。是否命中 ROLLUP 完全由 Doris 系统自动决定
ROLLUP 的数据是独立物理存储的。因此,创建的 ROLLUP 越多,占用的磁盘空间也就越大。同时对导入速度也会有影响,但是不会降低查询效率(只会更好)。
ROLLUP 的数据更新与 Base 表是完全同步的。用户无需关心这个问题。
在聚合模型中,ROLLUP 中列的聚合类型,与 Base 表完全相同。在创建 ROLLUP 无需指定,也不能修改。
可以通过 EXPLAIN your_sql; 命令获得查询执行计划,在执行计划中,查看是否命中 ROLLUP。
可以通过 DESC tbl_name ALL; 语句显示 Base 表和所有已创建完成的 ROLLUP