Doris(15):物化视图

news2024/12/24 3:51:44

1 概念

物化视图是将预先计算(根据定义好的 SELECT 语句)好的数据集,存储在 Doris 中的一个特殊的表。

物化视图的出现主要是为了满足用户,既能对原始明细数据的任意维度分析,也能快速的对固定维度进行分析查询。

首先,什么是物化视图?

从定义上来说,就是包含了查询结果的数据库对象,可能是对远程数据的本地Copy;也可能是一个表或多表Join后结果的行或列的子集;也可能是聚合后的结果。说白了,就是预先存储查询结果的一种数据库对象。

2 适用场景

  • 分析需求覆盖明细数据查询以及固定维度查询两方面。
  • 查询仅涉及表中的很小一部分列或行。
  • 查询包含一些耗时处理操作,比如:时间很久的聚合操作等。
  • 查询需要匹配不同前缀索引。

3 优势

  • 对于那些经常重复的使用相同的子查询结果的查询性能大幅提升。
  • Doris自动维护物化视图的数据,无论是新的导入,还是删除操作都能保证base 表和物化视图表的数据一致性。无需任何额外的人工维护成本。
  • 查询时,会自动匹配到最优物化视图,并直接从物化视图中读取数据。

自动维护物化视图的数据会造成一些维护开销,会在后面的物化视图的局限性中展开说明。

4 物化视图 VS Rollup

在没有物化视图功能之前,用户一般都是使用 Rollup 功能通过预聚合方式提升查询效率的。但是 Rollup 具有一定的局限性,他不能基于明细模型做预聚合。

物化视图则在覆盖了 Rollup 的功能的同时,还能支持更丰富的聚合函数。所以物化视图其实是 Rollup 的一个超集。

也就是说,之前 ALTER TABLE ADD ROLLUP 语法支持的功能现在均可以通过 CREATE MATERIALIZED VIEW 实现。

5 使用物化视图

Doris 系统提供了一整套对物化视图的 DDL 语法,包括创建,查看,删除。DDL 的语法和 PostgreSQL, Oracle都是一致的。

5.1 创建物化视图

这里首先你要根据你的查询语句的特点来决定创建一个什么样的物化视图。这里并不是说你的物化视图定义和你的某个查询语句一模一样就最好。这里有两个原则:

  • 从查询语句中抽象出,多个查询共有的分组和聚合方式作为物化视图的定义。
  • 不需要给所有维度组合都创建物化视图。

首先第一个点,一个物化视图如果抽象出来,并且多个查询都可以匹配到这张物化视图。这种物化视图效果最好。因为物化视图的维护本身也需要消耗资源。

如果物化视图只和某个特殊的查询很贴合,而其他查询均用不到这个物化视图。则会导致这张物化视图的性价比不高,既占用了集群的存储资源,还不能为更多的查询服务。

所以用户需要结合自己的查询语句,以及数据维度信息去抽象出一些物化视图的定义。

第二点就是,在实际的分析查询中,并不会覆盖到所有的维度分析。所以给常用的维度组合创建物化视图即可,从而到达一个空间和时间上的平衡。

通过下面命令就可以创建物化视图了。创建物化视图是一个异步的操作,也就是说用户成功提交创建任务后,Doris 会在后台对存量的数据进行计算,直到创建成功。

CREATE MATERIALIZED VIEW

具体的语法可以通过下面命令查看:

HELP CREATE MATERIALIZED VIEW

5.2 支持聚合函数

目前物化视图创建语句支持的聚合函数有:

  • SUM, MIN, MAX (Version 0.12)
  • COUNT, BITMAP_UNION, HLL_UNION (Version 0.13)
  • BITMAP_UNION 的形式必须为:BITMAP_UNION(TO_BITMAP(COLUMN)) column 列的类型只能是整数(largeint也不支持), 或者 BITMAP_UNION(COLUMN) 且 base 表为 AGG 模型。
  • HLL_UNION 的形式必须为:HLL_UNION(HLL_HASH(COLUMN)) column 列的类型不能是 DECIMAL , 或者 HLL_UNION(COLUMN) 且 base 表为 AGG 模型

使用限制:

  • DML:delete

使用物化视图功能后,由于物化视图实际上是损失了部分维度数据的。所以对表的 DML类型操作会有一些限制。

例如:如果表的物化视图Key中不包含删除语句中的条件列,则删除语句不能执行。如果想要删除渠道为APP端的数据,由于存在一个物化视图并不包含渠道这个字段,则这个删除不能执行,因为删除在物化视图中无法被执行。这时候你只能把物化视图先删除,然后删除完数据后,重新构建一个新的物化视图。 未来还会支持构建年表、月表,会用的到 to_mouth 和 to_day 函数。

5.3 更新策略

为保证物化视图表和 Base 表的数据一致性, Doris 会将导入,删除等对 base 表的操作都同步到物化视图表中。并且通过增量更新的方式来提升更新效率。通过事务方式来保证原子性。

比如如果用户通过 INSERT 命令插入数据到 base 表中,则这条数据会同步插入到物化视图中。当 base 表和物化视图表均写入成功后,INSERT 命令才会成功返回。

5.4 查询自动匹配

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

用户可以通过 EXPLAIN 命令来检查当前查询是否使用了物化视图。

物化视图中的聚合和查询中聚合的匹配关系:

5.5 查询物化视图

查看当前表都有哪些物化视图,以及他们的表结构都是什么样的。通过下面命令:

desc table all;

6 演示

6.1 创建base表

CREATE TABLE sales_records(
    id INT COMMENT "销售记录的id",
    seller_id INT COMMENT "销售员的id",
    store_id  INT COMMENT "门店的id",
    sale_date DATE COMMENT "售卖时间",
    sale_amt BIGINT COMMENT "金额"
)
DISTRIBUTED BY HASH(id) BUCKETS 10;

6.2 创建物化视图

CREATE MATERIALIZED VIEW mv_1 AS
SELECT seller_id,sale_date,SUM(sale_amt)
FROM sales_records
GROUP BY seller_id,sale_date;

提交完创建物化视图的任务后,Doris就会异步在后台生成物化视图的数据,构建物化视图。在构建期间,用户依然可以正常的查询和导入新的数据。创建任务会自动处理当前的存量数据和所有新到达的增量数据,从而保持和Base表的数据一致性。用户无需担心一致性问题。

6.3 查询物化视图

desc sales_records all;

6.4 物化视图匹配

基于这个Base表的数据再次提交两个创建物化视图的任务

CREATE MATERIALIZED VIEW mv_2 AS SELECT store_id,sale_date,SUM(sale_amt) 
FROM sales_records 
GROUP BY store_id,sale_date; 

CREATE MATERIALIZED VIEW mv_3 AS
SELECT seller_id,SUM(sale_amt)
FROM sales_records
GROUP BY seller_id;

查询物化视图

desc sales_records all;

执行查询语句,Doris会更加视图情况进行自动匹配相关视图

select seller_id,SUM(sale_amt) from sales_records where sale_date='2021-02-10' group by seller_id;

6.5 自动匹配

最优选择如下图:

 

物化视图的自动匹配分为下面两个步骤:

  • 根据查询条件筛选出一个最优的物化视图:这一步的输入是所有候选物化视图表的元数据,根据查询的条件从候选集中输出最优的一个物化视图
  • 根据选出的物化视图对查询进行改写:这一步是结合上一步选择出的最优物化视图,进行查询的改写,最终达到直接查询物化视图的目的。

删除、检查物化视图是否构建完成

-- 删除物化视图 
DROP MATERIALIZED VIEW mv_3 ON sales_records;

-- 检查物化视图是否构建完成 
SHOW ALTER TABLE MATERIALIZED VIEW FROM test_db;

6.6 选择最优

下面详细解释一下第一步最优物化视图是被如何选择出来的

这里分为两个步骤:

  • 对候选集合进行一个过滤。只要是查询的结果能从物化视图数据计算(取部分行,部分列,或部分行列的聚合)出都可以留在候选集中,过滤完成后候选集合大小 >= 1。
  • 从候选集合中根据聚合程度,索引等条件选出一个最优的也就是查询花费最少物化视图。

这里再举一个相对复杂的例子,来体现这个过程。

首先先说过滤候选集这个过程。

候选集过滤目前分为4层,每一层过滤后去除不满足条件的物化视图。

例如:查询2月10日各个销售员都买了多少钱。

首先候选集中包括所有的物化视图以及Base表共4个。

  • 第一层过滤先判断查询Where中的谓词涉及到的数据是否能从物化视图中得到,也就是销售时间列是否在表中存在。由于第三个物化视图中根本不存在销售时间列。所以在这一层过滤中,mv_3就被淘汰了。
  • 第二层是过滤查询的分组列是否为候选集的分组列的子集,也就是销售员id是否为表中分组列的子集。由于第二个物化视图中的分组列并不涉及销售员id。所以在这一层过滤中,mv_2也被淘汰了。
  • 第三层过滤是看查询的聚合列是否为候选集中聚合列的子集,也就是对销售额求和是否能从候选集的表中聚合得出。这里Base表和物化视图表均满足标准。
  • 最后一层是过滤看查询需要的列是否存在于候选集合的列中。由于候选集合中的表均满足标准,所以最终候选集合中的表为销售明细表,以及mv_1这两张。

候选集过滤完后输出一个集合,这个集合中的所有表都能满足查询的需求,但每张表的查询效率都不同。

这时候就需要在这个集合根据前缀索引是否能匹配到,以及聚合程度的高低来选出一个最优的物化视图。

例如:从表结构中可以看出,Base表的销售日期列是一个非排序列,而物化视图表的日期是一个排序列,同时聚合程度上mv_1表明显比Base表高。

所以最后选择出mv_1作为该查询的最优匹配。

6.7 查询改写

最后再根据选择出的最优解,改写查询。

例如:刚才的查询选中mv_1后,将查询改写为从mv_1中读取数据,过滤出日志为2月10日的mv_1中的数据然后返回即可。 

有些情况下的查询改写还会涉及到查询中的聚合函数的改写。比如业务方经常会用到Count、Distinct对PV、UV进行计算。

例如:

广告点击明细记录表中存放哪个用户点击了什么广告,从什么渠道点击的,以及点击的时间。并且在这个Base表基础上构建了一个物化视图表,存储了不同广告不同渠道的用户Bitmap值。

由于bitmap_union这种聚合方式本身会对相同的用户user_id进行一个去重聚合。当用户查询广告在Web端的UV的时候,就可以匹配到这个物化视图。匹配到这个物化视图表后就需要对查询进行改写,将之前的对用户id求 count(distinct) 改为对物化视图中bitmap_union列求count。

所以最后查询取物化视图的第一和第三行求Bitmap聚合中有几个值。

6.8 适用场景

上面介绍了两种数据模型——明细模型和聚合模型,也介绍了两种预聚合方式物化视图和Rollup。那么在数据模型的选择上:

  • 如果用户的分析都是固定维度的分析类查询,比如报表类业务,且完全不关心明细数据时,则用聚合模型最合适。
  • 如果用户需要查询明细数据,比如交易明细,则用明细模型合适。

对于物化视图和Rollup来说:

  • 他们的共同点都是通过预聚合的方式来提升查询效率。

实际上物化视图是Rollup的一个超集,在覆盖Rollup的工作同时,还支持更灵活的聚合方式。

因此,如果对数据的分析需求既覆盖了明细查询也存在分析类查询,则可以先创建一个明细模型的表,并构建物化视图。

7 局限性

  • 物化视图的聚合函数的参数不支持表达式仅支持单列,比如: sum(a+b)不支持。
  • 如果删除语句的条件列,在物化视图中不存在,则不能进行删除操作。如果一定要删除数据,则需要先将物化视图删除,然后方可删除数据。
  • 单表上过多的物化视图会影响导入的效率:导入数据时,物化视图和 base 表数据是同步更新的,如果一张表的物化视图表超过10张,则有可能导致导入速度很慢。
  • 相同列,不同聚合函数,不能同时出现在一张物化视图中,比如:select sum(a), min(a) from table 不支持。
  • 物化视图针对 Unique Key数据模型,只能改变列顺序,不能起到聚合的作用,所以在Unique Key模型上不能通过创建物化视图的方式对数据进行粗粒度聚合操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/449250.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】布尔类型(bool)

目录​​​​​​​ 1、缘起 2、笔记整理 4、用法 4.1、布尔变量的定义和初始化 4.2、布尔类型的运算符 4.3、布尔类型的条件语句 4.4、布尔类型的循环语句 5、总结 1、缘起 最近在 BiliBili 黑马程序员学习 C 编程语言,今天学习到了 布尔(b…

算法套路十二——回溯法之排列型回溯

算法套路十二——回溯法之排列型回溯 该节是在第十节回溯法之子集型回溯的基础上进行描写,组合型回溯会在子集型回溯的基础上判断所选子集是否符合组合要求, 故请首先阅读第十节算法套路十——回溯法之子集型回溯 算法示例一:LeetCode46. 全…

windows环境安装tensorflow-gpu-2.10.1

Tensorflow 2.10是最后一个在本地windows上支持GPU的版本 1. 通过.whl文件方式安装2.创建anaconda虚拟环境3.安装对应的cuda与cudnn版本,local不必装cuda和cudnn4. 测试tensorflow gpu是否可用 1. 通过.whl文件方式安装 .whl文件的下载地址: tensorflow…

Linux — 线程概念和线程控制

目录 一、 线程的概念 什么是线程? 线程的优点 线程的缺点 线程异常 线程用途 二、线程的控制 创建线程 pthread_create函数 线程终止 pthread_exit函数 pthread_cancel函数 线程等待 pthread_join函数 分离线程 一、 线程的概念 之前的文章说过每个进程有…

IDE后端启动JetLinks 物联网基础平台(2.x)

目录 一、官网 二、文档中心 三、下载源码 四、安装依赖 五、IDE配置 六、修改配置文件:jetlinks-standalone/src/main/resources/application.yml 七、启动项目(项目会自动建表) 一、官网 JetLinkshttps://www.jetlinks.cn/#/ 二、…

率先实现One-box量产后,这家厂商重磅发布智能底盘“三步走”战略

率先实现One-box和Two-box产品量产之后,利氪科技向业界发布了重要的产品布局规划及进展。 在4月18日开幕的上海国际车展上,利氪科技重磅发布了全新的智能化线控底盘产品矩阵,同时发布了智能底盘“三步走”计划。据了解,利氪科技将…

数据结构(五)—— 栈与队列

文章目录 前言一、基础1.1 stack1.2 queue 二、题2.1 232 用栈实现队列2.2 225 用队列实现栈2.3 20 有效的括号2.4 1047 删除字符串中的所有相邻重复项 前言 灵魂四问: 1、C中stack,queue 是容器么? 答:不是,而是容器…

高数基础3

目录 极限的概念,性质以及存在准则 求极限的方法 ​编辑 常用的基本极限 1的无穷次方常用的结论 例题: 方法2:利用等价无穷小代换求极限 例题: 常用的等价无穷小 利用有理运算法则求极限 例题 极限的概念,性质以…

【C语言】函数讲解(上)

【C语言】函数讲解(上) 1.函数是什么2.C语言中函数的分类2.1库函数2.1.1如何学会使用库函数 2.2.自定义函数 3.函数的参数3.1实际参数(实参)3.2形式参数(形参) 4.函数调用4.1传值调用4.2传址调用4.3练习 所…

Redis分布式锁实现方案

一、什么是分布式锁,与本地锁有什么区别 本地锁: 解决同一进程内多个线程操作同一资源的问题。 分布式锁: 解决多个进程同时操作同一资源的问题。 二、Redis的SETNX Redis之所以能实现分布式锁,得益于Redis的单线程处理模式&am…

Macbook(苹果电脑) VSCode 创建简单c++程序 配置C++开发环境

1.打开 Terminal 终端(Command空格,输入Terminal)。 1.1 输入如下指令,查看是否显示版本信息。 clang --version 1.2 如果出现版本信息,则跳过,否则输入 xcode-select --install 2. 为 VS Code 安装插件 …

docker中的四种网络模式

docker中的四种网络模式 实现原理四类网络模式host模式container模式none模式bridge模式 实现原理 Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Con…

MySQL_第06章_多表查询

第06章_多表查询 讲师:尚硅谷 - 宋红康(江湖人称:康师傅) 官网: http://www.atguigu.com 多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。 前提条件:这些一起查询的…

【Python】darts包(Python时序预测库的安装方法)+conda环境和库的建立

一、介绍 "darts"是一个Python编程语言中的数据处理和时间序列分析工具包。它提供了一系列用于处理、建模和分析时间序列数据的功能,包括时间序列的预处理、特征工程、模型训练和预测等。darts包含了许多常用的时间序列模型,如ARIMA、Prophet…

Linux权限 - 概念与管理 | 文件权限的修改与转让 【详解】

目录 Linux权限 Linux权限的概念 Linux权限的基础操作 (1).实现用户账号的切换 (2).仅提升当前指令的权限 Linux权限管理 1、文件访问者的分类(人) 2、文件类型和访问权限(事物属性) 3、文件权限值的表示方法 4、文件访…

数据结构与算法基础(王卓)(28):排序概述(分类)、直接插入排序思路

目录 排序分类:(本章目录) 按数据存储介质:(学习内容) 内部排序: 外部排序: 按比较器个数:(学习内容) 串行排序: 并行排序&…

arduino学习笔记2

一.蜂鸣器输出实验 1.源代码 int buzzer2;//设置控制蜂鸣器的数字口对应板子上2口 void setup() { pinMode(buzzer,OUTPUT);//设置对应的输出模式 } void loop() { unsigned char i,j;//定义变量while(1) { for(i0;i<50;i)//输出一个频率的声音{ digitalWrite(buzzer,H…

2023年4月的12篇AI论文推荐

GPT-4发布仅仅三周后&#xff0c;就已经随处可见了。本月的论文推荐除了GPT-4以外还包括、语言模型的应用、扩散模型、计算机视觉、视频生成、推荐系统和神经辐射场。 1、GPT-4 Technical Report Sbastien Bubeck, Varun Chandrasekaran, Ronen Eldan, Johannes Gehrke, Eric…

密码技术知识总结

密码技术知识总结 1. 密码技术简介 对称密码&#xff1a;加密和解密时使用同一密钥的方式公钥密码&#xff1a;加密和解密时使用不同密钥&#xff0c;也称非对称密码单向散列函数&#xff1a;保证数据的完整性&#xff0c;检测数据是否被篡改过 散列值&#xff1a;又称哈希值…

k8s 控制器---Statefulset

1. Statefulset 控制器 StatefulSet 是为了管理有状态服务的问题而设计的。 1.1 什么叫有状态服务&#xff1f; StatefulSet 是有状态的集合&#xff0c;管理有状态的服务&#xff0c;它所管理的 Pod 的名称不能随意变化。数据 持久化的目录也是不一样&#xff0c;每一个 Pod …