目录
1. 创建测试表
2. 创建Rollup物化索引表
3. 查看Rollup物化索引表
4. 删除Rollup物化索引表
5. 验证Rollup物化索引使用
进入正文之前,欢迎订阅专题、对博文点赞、评论、收藏,关注IT贫道,获取高质量博客内容!
宝子们点赞、收藏不迷路!抓紧订阅专题!
ROLLUP 在多维分析中是“上卷”的意思,即将数据按某种指定的粒度进行进一步聚合。在 Doris 中,我们将用户通过建表语句创建出来的表称为 Base 表(Base Table)。Base 表中保存着按用户建表语句指定的方式存储的基础数据。
Rollup 可以理解为Base Table 的一个物化索引结构,“物化”是因为其数据在物理上独立存储,而“索引”的意思是,建立 Rollup 时可只选取 Base Table 中的部分列作为 Schema,Schema 中的字段顺序也可与 Base Table 不同,所以Rollup可以调整列顺序以增加前缀索引的命中率,也可以减少key列以增加数据的聚合度。
在 Base 表之上,我们可以创建任意多个 ROLLUP 物化索引表,这些 ROLLUP 的数据是基于 Base 表产生的,并且在物理上是独立存储的。ROLLUP 物化索引表的基本作用,在于在 Base 表的基础上,获得更粗粒度的聚合数据。
1. 创建测试表
创建表 tbl1,建表SQL语句如下:
CREATE TABLE IF NOT EXISTS example_db.tbl1
(
`siteid` BIGINT NOT NULL COMMENT "网站id",
`citycode` SMALLINT NOT NULL COMMENT "城市编码",
`username` VARCHAR(32) NOT NULL COMMENT "用户名称",
`pv` BIGINT SUM NOT NULL DEFAULT "0" COMMENT "pv值",
`uv` BIGINT SUM NOT NULL DEFAULT "0" COMMENT "uv值"
)
AGGREGATE KEY(`siteid`, `citycode`, `username`)
DISTRIBUTED BY HASH(`siteid`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
并向表中插入如下20条数据:
insert into example_db.tbl1 values
(101,1,"陈家伟",20,10),
(102,2,"童启光",21,11),
(103,1,"丁俊毅",22,12),
(104,2,"林正平",23,13),
(105,1,"王雅云",24,14),
(101,2,"陈家伟",25,15),
(102,1,"童启光",26,16),
(103,2,"丁俊毅",27,17),
(104,1,"林正平",28,18),
(105,2,"王雅云",29,19),
(101,1,"陈家伟",30,20),
(102,2,"童启光",31,21),
(103,1,"丁俊毅",32,22),
(104,2,"林正平",33,23),
(105,1,"王雅云",34,24),
(101,2,"陈家伟",35,25),
(102,1,"童启光",36,26),
(103,2,"丁俊毅",37,27),
(104,1,"林正平",38,28),
(105,2,"王雅云",39,29);
表中数据如下:
对于 tbl1明细数据是 siteid, citycode, username 三者构成一组 key,从而对 pv 、uv字段进行聚合;如果业务方经常有看城市 pv 总量的需求,可以建立一个只有 citycode, pv 的rollup,这就可以通过创建Rollup物化索引表来实现。
2. 创建Rollup物化索引表
基于Base表创建Rollup物化索引表语法如下:
ALTER TABLE [database.]table ADD ROLLUP rollup_name (column_name1, column_name2, ...)
对tbl1表创建只有citycode,pv两列的Rollup物化索引表,指定rollup_name为rollup_city,SQL如下:
mysql> ALTER TABLE tbl1 ADD ROLLUP rollup_city(citycode, pv);
Query OK, 0 rows affected (0.03 sec)
创建Rollup物化索引表过程是一个异步命令,SQL执行完成并不意味着Rollup表创建完成,创建的Rollup物化索引表rollup_city中只有citycode、pv两列,可以通过以下SQL来查询Rollup表作业的进度:
mysql> SHOW ALTER TABLE ROLLUP\G;
*************************** 1. row ***************************
JobId: 18389
TableName: tbl1
CreateTime: 2023-02-09 21:14:57
FinishTime: 2023-02-09 21:15:19
BaseIndexName: tbl1
RollupIndexName: rollup_city
RollupId: 18390
TransactionId: 4016
State: FINISHED
Msg:
Progress: NULL
Timeout: 2592000
1 rows in set (0.01 sec)
当作业状态为 FINISHED,则表示作业完成。也可以执行如下命令取消正在执行的作业:
CANCEL ALTER TABLE ROLLUP FROM table1;
3. 查看Rollup物化索引表
Rollup物化索引表创建完成后使用如下命令查看表的Rollup信息:
DESC [database.]table ALL
查看表tbl1的rollup物化索引信息:
4. 删除Rollup物化索引表
删除Rollup物化索引表命令如下:
ALTER TABLE [database.]table DROP ROLLUP rollup_name;
执行如下SQL删除tbl1上名为rollup_city的rollup物化索引表:
5. 验证Rollup物化索引使用
Rollup 建立之后,查询不需要指定 Rollup 进行查询,还是指定原有表进行查询即可。程序会自动判断是否应该使用 Rollup。是否命中 Rollup可以通过 EXPLAIN your_sql; 命令进行查看,查看执行该命令最后“VOlapScanNode”部分查询的TABLE即可。
下面我们对表执行如下SQL语句,查看explain信息:
mysql> explain select citycode ,sum(pv) from tbl1 group by citycode;
...
| 0:VOlapScanNode |
| TABLE: default_cluster:example_db.tbl1(tbl1), PREAGGREGATION: ON |
| partitions=1/1, tablets=10/10, tabletList=18368,18370,18372 ... |
| cardinality=5, avgRowSize=2490.0, numNodes=3
...
我们可以看到由于删除了rollup物化索引表,所以无法从rollup物化索引表中进行查询,下面我们重新基于tbl1创建Rollup物化索引表rollup_city:
mysql> ALTER TABLE tbl1 ADD ROLLUP rollup_city(citycode, pv);
Query OK, 0 rows affected (0.03 sec)
#查看是否创建完成
mysql> SHOW ALTER TABLE ROLLUP\G;
当Rollup物化索引表创建完成后,重新执行explain SQL,我们发现命中了创建的Rollup物化索引表。
mysql> explain select citycode ,sum(pv) from tbl1 group by citycode;
...
| 0:VOlapScanNode
|
|TABLE: default_cluster:example_db.tbl1(rollup_city), PREAGGREGATION: ON |
| partitions=1/1, tablets=10/10, tabletList=19029,19031,19033 ... |
| cardinality=5, avgRowSize=0.0, numNodes=3
...
通过“select citycode ,sum(pv) from tbl1 group by citycode”SQL查询可以看到Doris会自动命中Rollup物化索引表,从而只需要扫描极少的数据量,即可完成聚合查询。