doris

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

3.5.1基本概念

通过建表语句创建出来的表称为 Base 表(Base Table,基表)
在 Base 表之上,我们可以创建任意多个 ROLLUP 表。这些 ROLLUP 的数据是基于 Base 表产生的,并且在物理上是 独立存储的。
Rollup表的好处:
  1. 和基表共用一个表名,doris会根据具体的查询逻辑选择合适的数据源(合适的表)来计算结果
  2. 对于基表中数据的增删改,rollup表会自动更新同步

3.5.2 Aggregate 模型中的 ROLLUP

 
   
示例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;
再次查看该表得详细信息后发现,多了一个IndexName为rollup_cost_userid(这是我们自己取得roll
Up 名字)
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得,相对来说效率会高很多

3.5.3 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;
插入语句
 
   
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');
很显然,里面的数据是这样的
 
   
mysql> select * from user; +---------+----------+--------+------+------+-------------+------------------+---------------------+ | user_id | username | city | age | sex | phone | address | register_time | +---------+----------+--------+------+------+-------------+------------------+---------------------+ | 10000 | lss | 北京 | 20 | 0 | 12345678910 | 北京海淀区 | 2017-11-15 06:10:20 | | 10000 | zss | 北京 | 19 | 0 | 12345678910 | 北京朝阳区 | 2017-10-01 07:00:00 | +---------+----------+--------+------+------+-------------+------------------+---------------------+
在unique模型中做rollup表,rollup的key必须 延用base表中所有的key,不同的是value可以随意指定
 
   
alter table user add rollup rollup_username_id(username,user_id,age);
所以说,unique模型中建立rollup表没有什么太多的意义
试想一下:
如果不沿用base表中所有的key,只针对上面的user_id进行rollup,那么他的age值取20还是19呢?好像也就不确定了,毕竟底层的aggregationType 用的是replace,到底谁替换谁就不确定了

3.5.4 Duplicate 模型中的 ROLLUP

因为 Duplicate 模型没有聚合的语意。所以该模型中的 ROLLUP,已经失去了“上卷” 这一层含义。而仅仅是作为调整列顺序,以命中前缀索引的作用。下面详细介绍前缀索引,以及如何使用 ROLLUP 改变前缀索引,以获得更好的查询效率。
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 的前缀索引匹配度更高。
示例:针对上面的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表
 
   
mysql> desc log_detail all; +------------+---------------+------------+---------------+------+-------+---------+-------+---------+ | IndexName | IndexKeysType | Field | Type | Null | Key | Default | Extra | Visible | +------------+---------------+------------+---------------+------+-------+---------+-------+---------+ | log_detail | DUP_KEYS | timestamp | DATETIME | No | true | NULL | | true | | | | type | INT | No | true | NULL | | true | | | | error_code | INT | Yes | false | NULL | NONE | true | | | | error_msg | VARCHAR(1024) | Yes | false | NULL | NONE | true | | | | op_id | BIGINT | Yes | false | NULL | NONE | true | | | | op_time | DATETIME | Yes | false | NULL | NONE | true | | | | | | | | | | | | rollup_oec | DUP_KEYS | op_id | BIGINT | Yes | true | NULL | | true | | | | error_code | INT | Yes | true | NULL | | true | | | | timestamp | DATETIME | No | true | NULL | | true | | | | type | INT | No | false | NULL | NONE | true | | | | error_msg | VARCHAR(1024) | Yes | false | NULL | NONE | true | | | | op_time | DATETIME | Yes | false | NULL | NONE | true | | | | | | | | | | | | rollup_tec | DUP_KEYS | type | INT | No | true | NULL | | true | | | | error_code | INT | Yes | true | NULL | | true | | | | timestamp | DATETIME | No | true | NULL | | true | | | | error_msg | VARCHAR(1024) | Yes | false | NULL | NONE | true | | | | op_id | BIGINT | Yes | false | NULL | NONE | true | | | | op_time | DATETIME | Yes | false | NULL | NONE | true | +------------+---------------+------------+---------------+------+-------+---------+-------+---------+
示例:看如下sql会命中哪一张表
 
   
explain select * from log_detail where type = 1; explain select * from log_detail where type = 1 and error_code = 404; explain select * from log_detail where op_id = 101 ; explain select * from log_detail where op_id = 101 and error_code = 404; explain select * from log_detail where timestamp = '2017-10-01 08:00:05' ; explain select * from log_detail where timestamp = '2017-10-01 08:00:05' and type = 1;
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

你可能感兴趣的:(数据库)