tnblog
首页
视频
资源
登录

Doris 物化视图(学习笔记)

55人阅读 2025/4/6 11:03 总访问:3493304 评论:0 收藏:0 手机
分类: 大数据

Doris 物化视图(学习笔记)


就是查询结果预先存储起来的特殊的表。
物化视图的出现主要是为了满足用户,既能对原始明细数据的任意维度分析,也能快速的对固定维度进行分析查询。

优势


1.可以复用预计算的结果来提高查询效率 ==> 空间换时间
2.自动实时的维护物化视图表中的结果数据,无需额外人工成本(自动维护会有计算资源的开销)
3.查询时,会自动选择最优物化视图

物化视图 VS Rollup


明细模型表下,rollup和物化视图的差别:
物化视图:都可以实现预聚合,新增一套前缀索引
rollup:对于明细模型,新增一套前缀索引
聚合模型下,功能一致

物化视图和rollup 本身特别像
在聚合模型下,功能一样,自行选择使用哪种,因为都一样。
对于明细模型来讲:rollup除了可以增加一套前缀索引之外,没有其他特别的用途。
假如你的表刚好是明细模型的表,又想使用rollup 的效果,此时可以选择使用物化视图。

创建物化视图


语法:

  1. CREATE MATERIALIZED VIEW [MV name] as
  2. [query] -- sql逻辑
  3. --[MV name]:雾化视图的名称
  4. --[query]:查询条件,基于base表创建雾化视图的逻辑
  5. 取消正在创建的物化视图
  6. CANCEL ALTER MATERIALIZED VIEW FROM db_name.table_name


物化视图创建成功后,用户的查询不需要发生任何改变,也就是还是查询的 base 表。
Doris 会根据当前查询的语句去自动选择一个最优的物化视图,从物化视图中读取数据并计算。
用户可以通过 EXPLAIN 命令来检查当前查询是否使用了物化视图。

案例演示


创建一个 Base 表:
用户有一张销售记录明细表,存储了每个交易的交易id,销售员,售卖门店,销售时间,以及金额。

  1. drop table sales_records;
  2. create table sales_records(
  3. record_id int,
  4. seller_id int,
  5. store_id int,
  6. sale_date date,
  7. sale_amt bigint)
  8. duplicate key (record_id,seller_id,store_id,sale_date)
  9. distributed by hash(record_id) buckets 2
  10. properties("replication_num" = "1");
  11. -- 插入数据
  12. insert into sales_records values
  13. (1,1,1,'2022-02-02',100),
  14. (2,2,1,'2022-02-02',200),
  15. (3,3,2,'2022-02-02',300),
  16. (4,3,2,'2022-02-02',200),
  17. (5,2,1,'2022-02-02',100),
  18. (6,4,2,'2022-02-02',200),
  19. (7,7,3,'2022-02-02',300),
  20. (8,2,1,'2022-02-02',400),
  21. (9,9,4,'2022-02-02',100);


如果用户需要经常对不同门店的销售量进行统计
第一步:创建一个物化视图

  1. -- 不同门店,看总销售额的一个场景
  2. select store_id, sum(sale_amt)
  3. from sales_records
  4. group by store_id;
  5. --针对上述场景做一个物化视图
  6. create materialized view store_amt as
  7. select store_id, sum(sale_amt) as sum_amount
  8. from sales_records
  9. group by store_id;

创建物化视图的sql语句在datagrip 中报错,没有办法创建(将来新的版本可能会支持),需要在黑窗口执行该命令创建。
第二步:检查物化视图是否构建完成(物化视图的创建是个异步的过程)

  1. show alter table materialized view from 库名 order by CreateTime desc limit 1;
  2. show alter table materialized view from test order by CreateTime desc limit 1;

  1. 查看 Base 表的所有物化视图
  2. desc sales_records all;


第三步:查询
看是否命中刚才我们建的物化视图

  1. EXPLAIN SELECT store_id, sum(sale_amt) FROM sales_records GROUP BY store_id;


测试一下没有添加物化视图的sql:

  1. EXPLAIN
  2. select seller_id, sum(sale_amt)
  3. from sales_records
  4. group by seller_id;


删除物化视图语法

  1. -- 语法:
  2. DROP MATERIALIZED VIEW 物化视图名 on base_table_name;
  3. --示例:
  4. drop materialized view store_amt on sales_records;

案例一:计算广告的 pv、uv


pv : 整个网站的网页访问量
uv: 一个网站的访问人数

  1. drop table if exists ad_view_record;
  2. create table ad_view_record(
  3. dt date,
  4. ad_page varchar(10),
  5. channel varchar(10),
  6. refer_page varchar(10),
  7. user_id int
  8. )
  9. distributed by hash(dt)
  10. properties("replication_num" = "1");


插入数据

  1. insert into ad_view_record values
  2. ('2020-02-02','a','app','/home',1),
  3. ('2020-02-02','a','web','/home',1),
  4. ('2020-02-02','a','app','/addbag',2),
  5. ('2020-02-02','b','app','/home',1),
  6. ('2020-02-02','b','web','/home',1),
  7. ('2020-02-02','b','app','/addbag',2),
  8. ('2020-02-02','b','app','/home',3),
  9. ('2020-02-02','b','web','/home',3),
  10. ('2020-02-02','c','app','/order',1),
  11. ('2020-02-02','c','app','/home',1),
  12. ('2020-02-03','c','web','/home',1),
  13. ('2020-02-03','c','app','/order',4),
  14. ('2020-02-03','c','app','/home',5),
  15. ('2020-02-03','c','web','/home',6),
  16. ('2020-02-03','d','app','/addbag',2),
  17. ('2020-02-03','d','app','/home',2),
  18. ('2020-02-03','d','web','/home',3),
  19. ('2020-02-03','d','app','/addbag',4),
  20. ('2020-02-03','d','app','/home',5),
  21. ('2020-02-03','d','web','/addbag',6),
  22. ('2020-02-03','d','app','/home',5),
  23. ('2020-02-03','d','web','/home',4);


创建物化视图

  1. -- 怎么去计算pvuv
  2. select
  3. dt,ad_page,channel,
  4. count(ad_page) as pv,
  5. count(distinct user_id) as uv
  6. from ad_view_record
  7. group by dt,ad_page,channel;
  8. -- 1.物化视图中,不能够使用两个相同的字段
  9. -- 2.在增量聚合里面,不能够使用count(distinct) ==> bitmap_union
  10. -- 3.count(字段)
  11. create materialized view dpc_pv_uv as
  12. select
  13. dt,ad_page,channel,
  14. -- refer_page 没有null的情况
  15. count(refer_page) as pv,
  16. -- doris的物化视图中,不支持count(distint) ==> bitmap_union
  17. -- count(distinct user_id) as uv
  18. bitmap_union(to_bitmap(user_id)) uv_bitmap
  19. from ad_view_record
  20. group by dt,ad_page,channel;
  21. //1. count(必须加字段名) 不能写count(1)
  22. //2.同一个字段在物化视图的sql逻辑中不能出现两次
  23. //3. count(distinct) 不能使用。需要用bitmap_union来代替
  24. create materialized view tpc_pv_uv as
  25. select
  26. dt,ad_page,channel,
  27. count(refer_page) as pv,
  28. -- refer_page 不能为null
  29. -- count(user_id) as pv
  30. -- count(1) as pv,
  31. bitmap_union(to_bitmap(user_id)) as uv_bitmap
  32. --count(distinct user_id) as uv
  33. from ad_view_record
  34. group by dt,ad_page,channel;
  35. --结论:在doris的物化视图中,一个字段不能用两次,并且聚合函数后面必须跟字段名称


在 Doris 中,count(distinct) 聚合的结果和 bitmap_union_count 聚合的结果是完全一致的。而 bitmap_union_count 等于 bitmap_union 的结果求 count,所以如果查询中涉及到count(distinct) 则通过创建带 bitmap_union 聚合的物化视图方可加快查询。因为本身 user_id 是一个 INT 类型,所以在 Doris 中需要先将字段通过函数 to_bitmap 转换为 bitmap 类型然后才可以进行 bitmap_union 聚合。
查询自动匹配

  1. explain
  2. select
  3. dt,ad_page,channel,
  4. count(refer_page) as pv,
  5. count(distinct user_id) as uv
  6. from ad_view_record
  7. group by dt,ad_page,channel;


用到了物化视图

  1. explain
  2. select
  3. dt,ad_page,channel,
  4. count(1) as pv,
  5. bitmap_union_count(to_bitmap(user_id)) as uv
  6. from ad_view_record
  7. group by dt,ad_page,channel;


这样查询没有用到物化视图。
当然,我们还可以根据日期和页面的维度再去创建一张物化视图

  1. create materialized view tp_pv_uv as
  2. select
  3. dt,ad_page,
  4. count(refer_page) as pv,
  5. bitmap_union(to_bitmap(user_id)) as uv
  6. from ad_view_record
  7. group by dt,ad_page;


再去执行上面的sql,显然命中的就是tp_pv_uv这个物化视图

  1. explain
  2. select
  3. dt,ad_page,
  4. count(refer_page) as pv,
  5. count(distinct user_id) as uv
  6. from ad_view_record
  7. group by dt,ad_page;
  8. -- TABLE: ad_view_record_1(tp_pv_uv), PREAGGREGATION: ON
  9. explain
  10. select
  11. dt,
  12. count(refer_page) as pv,
  13. count(distinct user_id) as uv
  14. from ad_view_record
  15. group by dt;


总结:
1.在创建doris的物化视图中,同一个字段不能被使用两次,并且聚合函数后面必须跟字段名称(不能使用count(1)这样的聚合逻辑)
2.doris在选择使用哪一个物化视图表的时候,按照维度上卷rollup的原则,选距离查询维度最接近,并且指标可以复用的物化视图.
3.一张基表可以创建多个物化视图(计算资源占用比较多)

案例二:调整前缀索引


场景:用户的原始表有(k1, k2, k3)三列。其中 k1, k2 为前缀索引列。
这时候如果用户查询条件中包含 where k1=1 and k2=2 就能通过索引加速查询。
但是有些情况下,用户的过滤条件无法匹配到前缀索引,比如 where k3=3。则无法通过索引提升查询速度。
解决方法:
创建以 k3 作为第一列的物化视图就可以解决这个问题。
查询

  1. desc sales_records all;


针对上面的前缀索引情况,执行下面的sql是无法利用前缀索引的

  1. explain
  2. select record_id,seller_id,store_id from sales_records
  3. where store_id=3;


创建物化视图

  1. create materialized view sto_rec_sell as
  2. select
  3. store_id,
  4. record_id,
  5. seller_id,
  6. sale_date,
  7. sale_amt
  8. from sales_records;


通过上面语法创建完成后,物化视图中既保留了完整的明细数据,且物化视图的前缀索 引为 store_id 列。
3)查看表结构

  1. desc sales_records all;


查询匹配

  1. explain select record_id,seller_id,store_id from sales_records where store_id=3;


这时候查询就会直接从刚才创建的sto_rec_sell物化视图中读取数据。物化视图对 store_id是存在前缀索引的,查询效率也会提升。


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

Windows Docker Doris 容器部署

Windows Docker Doris 容器部署[TOC] 引言Doris 是一款高性能、分布式、可扩展的分析型数据库,适用于海量数据的存储和分...

Doris 分区与桶学习笔记

Doris 分区与桶(学习笔记)[TOC] OLTP和OLAPOLTP联机事务处理OLTP(On-Line Transaction Processing) 公司针对自己公司的...

Doris 三种模型学习笔记

Doris 三种模型(学习笔记)[TOC] Aggregate聚合键模型是相同key的数据进行自动聚合的表模型。表中的列按照是否设置了 Agg...

Doris 数据的导入导出学习笔记

Doris 数据的导入导出(学习笔记)[TOC] 使用 Insert 方式同步数据用户可以通过 MySQL 协议,使用 INSERT 语句进行数据导...

Doris 突然内存升高解决方案

Doris 突然内存升高解决方案[TOC] 发现频繁refresh catalog xxx 会强制使对象相关的Cache失效,默认开启的采样也比较耗...

Doris 查询

Doris 查询[TOC] Doris的查询语法SELECT [ALL | DISTINCT | DISTINCTROW ] -- 对查询字段的结果是否需要去重...

Doris 作业案例

Doris 作业案例[TOC] 打地鼠案例需求:连续4次命中的人seq:第几次打地鼠m:是否命中,1-> 命中,0 -> 未命中下面是h...

Doris 索引学习笔记

Doris 索引(学习笔记)[TOC] 索引索引用于帮助快速过滤或查找数据。目前 Doris 主要支持两类索引:● 内建的智能索引:包...

Doris Rollup学习笔记

Doris Rollup(学习笔记)[TOC] ROLLUP 在多维分析中是“上卷”的意思,即将数据按某种指定的粒度进行进一步聚合。之前的...

Doris 中join的优化原理学习笔记

Doris 中join的优化原理(学习笔记)[TOC] Shuffle Join(Partitioned Join)Shuffle Join 是:把 A 表和 B 表的数据都根...

C ?、?? 问号和2个问号的用法类型?、对象?

C# ?C# ???:单问号1.定义数据类型可为空。可用于对int,double,bool等无法直接赋值为null的数据类型进行null的赋值如这...

Python实例 1-日志抓取处理 补错附日志小技巧

有时候数据出了问题,可以从日志中恢复数据(如果你没记日志..没备份..→_→..)一、日志展示介绍个平常自己用的小方法,如...

C 数组拆分泛型

主要用到了泛型。泛型是c#2.0的一个新增加的特性,它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。不会强行对值...

MySQL 视图的增删改 查

要显示视图的定义,需要在SHOWCREATEVIEW子句之后指定视图的名称, 我们先来创建几张表,完事后在进行演示:--用户信息表...

使用NPOI导出excel包括图片

Excl模板导出相信我们都会,那么模板上要导出图片呢?嗯~还是来个例子:准备工作:首先要引用NPOI包:然后获取数据集(我这...
这一世以无限游戏为使命!
排名
2
文章
639
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术