从一个问题开始聊聊clickhouse的物化视图

news2024/10/25 8:28:16

【问题】

今天有A问我一个问题,我明明创建了一个物化视图,源表是有数据的,为什么查询物化视图就没有数据?

创建物化视图的SQL示意如下:

CREATE MATERIALIZED VIEW schema1.test_mv
            on cluster clusterName
            TO schema1.test_dtl
            (
             `field_a` UInt64,
             `field_b` UInt32,
             `field_f` Int8
                )
AS
SELECT t1.field_a,
       t2.field_b,
       t3.field_f
FROM schema1.table1 AS t1
         LEFT JOIN
     (
         SELECT field_a,
                field_b
         FROM schema1.table4 t4
         ) AS t2 ON t1.field_a = toUInt64(t2.field_a)
         LEFT JOIN schema1.table3 AS t3 ON t2.field_b = t3.field_e
WHERE (t1.create_type = 1)

A的意思是

SELECT t1.field_a,
       t2.field_b,
       t3.field_f
FROM schema1.table1 AS t1
         LEFT JOIN
     (
         SELECT field_a,
                field_b
         FROM schema1.table4 t4
         ) AS t2 ON t1.field_a = toUInt64(t2.field_a)
         LEFT JOIN schema1.table3 AS t3 ON t2.field_b = t3.field_e
WHERE (t1.create_type = 1)

是有数据的,但是直接查

select * from schema1.test_mv是没数据的

由于我很久没有用物化视图,也是愣了一下,自己动手做了些实验才搞懂。

其实,如果熟悉clickhouse物化视图的特性,就知道创建的物化视图并不会把创建之前的数据给加载进来,只会把创建物化视图后的数据加载进来,所以一开始查不到数据是正常的。

借这个机会,我也边做实验边复习了一下物化视图的相关知识。

物化视图的机制是什么

一个物化视图的实现是这样的:当向SELECT中指定的表插入数据时,检测到有物化视图跟它关联,会针对这批写入的数据进行物化操作。即插入数据的一部分被这个SELECT查询转换,结果插入到视图中。

物化视图其实是数据库中的预计算逻辑+显式缓存,典型的空间换时间思路。

物化视图可以计算聚合,重组表主索引和排序顺序,可以很好地跨大量节点和处理大型数据集。

因此,ClickHouse 中的物化视图更像是插入触发器。 如果视图查询中有一些聚合,则它仅应用于一批新插入的数据。 对源表现有数据的任何更改(如更新、删除、删除分区等)都不会更改物化视图。

为什么需要物化视图

想像一个场景:有一个大的用户日志表,需要每个小时统计一些用户行为指标(例如登录时长)

如果每个小时都从这个大表里面去读,则由于数据量太大,效率很慢,而且对这个表的压力会很大(尤其是各种指标需求都需要访问这个表)。

有一个方法如果对 用户日志表 进行预聚合,把结果保存到一个新表 xx_mv,并随着 用户日志表 增量实时更新,每次去查询xx_mv 就可以了。

这就是物化视图的其中一个作用。

为何物化视图比表查询快

一般来说物化视图会快一些。

因为物化视图相当于物理表,已经将符合条件的数据存入物理的物化视图表中,查询已经和原来的基表没有关系,因此一般来说物化视图的数据量会远小于原来的基表。

而直接查询或者使用一般的视图还是要在原来的基表中查询。

物化视图在复杂的SQL查询的时候效果就很明显了,可以把一个查询出来的数据存到物理空间里,还可以创建索引、排序等等。

下面我们用具体的实验例子来看看这些特性。

物化视图的几个有趣的特性

物化视图与表一样可以指定表引擎、分区键、主键和表设置参数

例如:

CREATE MATERIALIZED VIEW test_mv

ENGINE = SummingMergeTree

PARTITION BY toYYYYMM(ctime) ORDER BY (userid)

AS SELECT

 xxx

FROM table WHERE ctime >= toDateTime('2024-01-01 00:00:00')

GROUP BY userid

物化视图并不会把创建之前的数据给加载进来

准备表table1,table2,talbe4,里面灌入相关数据,然后执行:

SELECT t1.field_a, t1.field_b, t3.field_f FROM schema1.table1 AS t1 LEFT JOIN ( SELECT field_a, field_b FROM schema1.table4 t4 ) AS t2 ON t1.field_a = toUInt64(t2.field_a) LEFT JOIN schema1.table3 AS t3 ON t2.field_b = t3.field_e WHERE (t1.create_type = 1)

返回数据是500+

此时还没创建物化视图

然后创建物化视图:

CREATE MATERIALIZED VIEW schema1.test_mv
            on cluster clusterName
            TO schema1.test_dtl
            (
             `field_a` UInt64,
             `field_b` UInt32,
             `field_f` Int8
                )
AS
SELECT t1.field_a,
       t2.field_b,
       t3.field_f
FROM schema1.table1 AS t1
         LEFT JOIN
     (
         SELECT field_a,
                field_b
         FROM schema1.table4 t4
         ) AS t2 ON t1.field_a = toUInt64(t2.field_a)
         LEFT JOIN schema1.table3 AS t3 ON t2.field_b = t3.field_e
WHERE (t1.create_type = 1)

其中schema1.test_dtl是新表的实体表,里面数据是空的。

查询创建好的物化视图和物化视图表:

select * from schema1.test_mv

select * from schema1.test_dtl

均返回空,表明物化视图并不会把创建之前的数据给加载进来

然后往table1中插入数据:

insert into schema.table1(field_a,create_type)  values(1,1),(2,1);

然后查询

物化视图和物化视图表:

select * from schema1.test_mv

select * from schema1.test_dtl

均返回相同的两条数据,表明当向SELECT中指定的表插入数据时,检测到有物化视图跟它关联,会针对这批写入的数据进行物化操作

这里就有一个问题:为什么有了物化视图,还需要加个物化视图表?

其实就是问要不要创建物化视图时进行 [TO[db.]name] 配置

如果创建物化视图时不带TO [db].[table],且必须指定ENGINE用于存储数据的表引擎,和建表类似,这种方法ClickHouse会创建一个隐藏的目标表(私有表)来保存视图数据,可以通过SHOW TABLES查看(inner_id开头的表);删除视图,私有表会消失;

如果使用TO [db].[table]创建物化视图,[db].[table]必须是一张已经存在的表,用来保存视图数据,此时创建物化视图相当于在表上面附加了一个物化视图。

需要注意,间接创建不能使用POPULATE关键字。

配置的好处:可以明确指定物化视图的存储位置,避免与其他表或视图产生名称冲突或者误删误操作。

另外,如果物化视图表本身是有数据的,那么在创建物化视图后,该物化视图就会含有该物化视图表的数据。

不指定POPULATE时如何初始化

clickhouse有POPULATE关键字的,但是不建议使用POPULATE,因为在创建视图期间插入基础表中的数据不会被插入物化视图,会造成数据的丢失。

如果指定POPULATE,则在创建视图时将现有表数据插入到视图中,就像创建一个CREATE TABLE ... AS SELECT ...一样。

那么在不用POPULATE的前提下,怎么进行物化视图的初始化?其实很简单:在 MV 建好之后将数据手动insert into test_mv select * from 来导入数据到 MV 

对源表现有数据的任何更改(如更新、删除、删除分区等)都不会更改物化视图

还是使用上面创建好的test_mv,由于前面我们执行

insert into schema.table1(field_a,create_type)  values(1,1),(2,1);

所以目前test_mv里面有两条数据。

我们修改table1中的数据:

alter table schema.table1_replica(本地表) on cluster  clusterName

update create_type=2 where field_a=1

按照前面的创建物化视图的sql,我们知道只会把schema.table1里面create_type=1的数据纳入物化视图,因此,我们去查现有的test_mv:

select * from schema1.test_mv

仍然是原先是两条数据。

因此可以证明,对源表现有数据的修改,不会更改物化视图

同理,物化视图不支持同步删除,若源表的数据不存在(删除了)则物化视图的数据仍然保留

在创建 MV 表时如用到了多表联查,只有当第一个查询的表有数据插入时,这个 MV 才会被触发

还是使用上面创建好的test_mv,目前有两条数据

(field_a,field_b,create_type) ==>(1,0,1),(2,0,1);

我们插入table4的数据:

insert into cs_data.table4(field_a,field_b) values(1,99999) ,(2,8888);

然后查询test_mv,发现数据没变,仍然是:

(field_a,field_b,create_type) ==>(1,0,1),(2,0,1);

而不是(field_a,field_b,create_type) ==>(1,99999,1),(2,888,1);

表明在创建 MV 表时如用到了多表联查,只有当第一个查询的表有数据插入时,这个 MV 才会被触发

无缝更改ClickHouse物化视图SELECT逻辑的方法  

无缝更改ClickHouse物化视图SELECT逻辑的方法-CSDN博客

物化视图的缺点

1.空间换时间,因此占空间。

2.使用难度较大,需要合理设计表结构对历史数据做聚合分析

3.仅支持插入触发,不支持历史数据的更新

4.它的本质是一个流式数据的使用场景,是累加式的技术,所以要用历史数据做去重、去更新的场景,就不适合

因此,如果一张表加了好多物化视图,在写这张表的时候,就会消耗很多机器的资源,比如数据带宽占满、存储一下子增加了很多。

物化视图适合的场景

1.解决表索引问题,我们可以用物化视图创建另外一种物理序,来满足某些条件下的查询问题。

2.可以借助 MergeTree 家族引擎(SummingMergeTree、Aggregatingmergetree等),得到一个实时的预聚合,满足快速查询。

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

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

相关文章

玩转安卓之配置gradle-8.2.1

概述:看了一下,由于gradle是国外的,所以下载速度很慢,这个老师又是很菜的类型,同学又不会,于是曹某就写这一篇文章,教大家学会简单的为安卓配置gradle-8.2.1。 第一步:下载gradle-8…

【问题解决】| 关于vscode调试python文件 报错 且直接运行正常的诡异情况记录

关于python的debug报错,其实很奇怪 首先,对于工作区代码,我们可以通过CtrlShiftP 来切换Python解释器 这样的话,工作区的代码就不会报import error 而且这样的话是可以运行跑通的,但最抽象的一集来了,这…

JavaScript 作用域详解:如何影响变量生命周期

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

总结Redis的原理

一、为什么要使用Redis 缓解数据库访问压力mysql读请求进行磁盘I/O速度慢,给数据库加Redis缓存(参考CPU缓存),将数据缓存在内存中,省略了I/O操作 二、Redis数据管理 2.1 redis数据的删除 定时删除惰性删除内存淘汰…

多层菜单的实现方案(含HierarchicalDataTemplate使用)

1、递归 下面是Winform的递归添加菜单栏数据,数据设置好父子id方便递归使用 在TreeView的控件窗口加载时,调用递归加载菜单 private void LoadTvMenu(){this.nodeList objService.GetAllMenu(); // 通过Service得到全部数据// 创建一个根节点this.t…

NCDA设计大赛中设定画命题解读

一年一度的未来设计师全国高校数字艺术设计大赛(NCDA)正在如火如荼的进行中,各高校的大学生和指导老师们也都在着手准备中。今天我们就特地来说说它的数字绘画命题之一的设定画选项,为了使大家更好地参加本次比赛,本文…

博客系统测试

文章目录 1.项目背景介绍2.功能介绍3.手动测试3.1编写测试用例3.2项目测试3.2.1登录测试3.2.2查看详情页面3.2.3编辑页面3.2.4删除博客3.2.5注销用户 大家好,我是晓星航。今天为大家带来的是 博客系统测试 相关的讲解!😀 1.项目背景介绍 项…

Vue.js+SpringBoot开发农村物流配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2.1 快递信息管理:2.2.2 位置信息管理:2.2.3 配送人员分配:2.2.4 路线规划:2.2.5 个人中心:2.2.6 退换快递处理:…

DxO ViewPoint:摄影师的最 佳拍档,记录世界的每一刻精彩 mac/win版

DxO ViewPoint是一款革命性的摄影软件,它以其独特的功能和卓越的性能,重新定义了摄影体验。这款软件不仅提供了丰富的摄影工具,还通过先进的算法和技术,让摄影师能够轻松捕捉、管理和展示他们的作品。 DxO ViewPoint 软件获取 Dx…

《幸运的基督徒》Python

题目描述 有15个基督徒和15个非基督徒在海上遇险, 为了能让一部分人活下来不得不将其中15个人扔到海里面去, 有个人想了个办法就是大家围成一个圈,由某个人开始从1报数, 报到9的人就扔到海里面,他后面的人接着从1开始报…

unity学习(49)——服务器三次注册限制以及数据库化角色信息4--角色信息数据库化

1.此处下断开始调试,list函数内就有问题: 2. 现在的问题是只读不写!32行就是写入部分的代码: 3. 很奇怪,调试的时候确实是写进来了 程序正常执行后,文件中数据也没有消失 关闭服务器文件内容依旧正常。 players包含所…

px2rem实现vue项目响应式布局

第一步 首先需要在项目中安装px2rem插件 npm install postcss-px2rem px2rem-loader --save 第二步 在项目src目录下新建util文件夹,在util文件夹下新建rem.js文件,内容如下: // rem等比适配配置文件 // 基准大小 const baseSize 14 //…

day14_异常

今日内容 零、 复习昨日 一、日期类 二、异常 零、 复习昨日 1为什么要重写toString Object类toString返回的是对象名字地址,无意义子类重写toString() 返回的对象属性内容 2为什么要重写equals Object类equals判断是对象的地址值是否相等,无意义子类重写equals,为了判断对象的…

电商分享沙龙干货:做印尼电商如何提高顾客购买意愿?

“得印尼者得东南亚” 这是诸多在印尼掘金的电商人的共识。2.7亿人口、GDP年增速稳定在5%、平均年龄在30岁上下、较强的消费能力……这些都使得印尼成为电商人掘金东南亚的首选之地。 图源:freepik 但近几年来,印尼政府不断调整关税,限制电商…

SAP MM学习笔记 - 错误 BMG140 - The material number is longer than the length set

错误 BMG140 - The material number is longer than the length set 品目编号大于长度设置 1,在新规品目的时候,出的错 2,OMSL 品目Code书式变更 IMG path>Logistic general>Material Master>Basic settings>Define output for…

滴滴基于 Clickhouse 构建新一代日志存储系统

ClickHouse 是2016年开源的用于实时数据分析的一款高性能列式分布式数据库,支持向量化计算引擎、多核并行计算、高压缩比等功能,在分析型数据库中单表查询速度是最快的。2020年开始在滴滴内部大规模地推广和应用,服务网约车和日志检索等核心平…

电脑自带dll修复在哪里,dll修复工具一键修复dll丢失问题

xinput1_3.dll文件是一个Windows操作系统中的动态链接库(DLL)文件,它是微软DirectX软件开发包的一部分,主要用于支持游戏控制器和其他输入设备的交互。这个文件是DirectInput API的一个组件,DirectInput是DirectX中处理…

聚焦两会 | 从2024年政府工作报告看网络安全新机

在今年的《政府工作报告》(下面简称“报告”)中,除了对2023年里我国所取得的重大成就作了全面总结外,针对2024年全年经济社会发展作出的部署安排引起全国人民的关注。报告中与网络安全相关的内容也引起网络安全行业相关从事人员的…

wpf prism左侧抽屉式菜单

1.首先引入包MaterialDesignColors和MaterialDesignThemes 2.主页面布局 左侧菜单显示在窗体外&#xff0c;点击左上角菜单图标通过简单的动画呈现出来 3.左侧窗体外菜单 <Grid x:Name"GridMenu" Width"150" HorizontalAlignment"Left" Ma…

TypeScript 中类、接口、枚举、函数、命名空间与模块的理解?应用场景?

文章目录 类、接口、枚举定义使用方式**1. 类**继承修饰符私有修饰符受保护修饰符只读修饰符 静态属性抽象类 接口 interface枚举 enum数字枚举字符串枚举异构枚举本质 函数function可选参数剩余类型函数重载 模块命名空间命名空间与模块区别应用场景有需要的请私信博主&#x…