当前位置: 首页 > news >正文

ClickHouse 高性能实时分析数据库-物化视图篇

告别等待,秒级响应!这不只是教程,这是你驾驭PB级数据的超能力!我的ClickHouse视频课,凝练十年实战精华,从入门到精通,从单机到集群。点开它,让数据处理速度快到飞起,让你的职业生涯从此开挂!

全套视频教程联系博主

1 写在前面

clickhouse的物化视图你用对了吗???

在数据仓库领域,我们经常会遇到这样的场景:

  1. 原始数据量巨大:日志、事件流等数据以极高的速度写入。

  2. 查询模式固定:分析师或仪表盘(Dashboard)总是对这些原始数据进行固定的聚合查询,例如:

    1. 每分钟的网站访问量 (PV/UV)

    2. 每个商品的日销售额

    3. 每个接口的平均响应时间

如果每次查询都直接扫描原始数据表,即使 ClickHouse 性能卓越,当数据量达到千亿甚至万亿级别时,查询延迟也会增加,计算资源消耗巨大。

普通视图 (View) 能解决问题吗? 不能。普通视图只是一个查询别名,它不存储任何数据。每次查询视图时,实际上还是在执行视图定义中的那个复杂查询,扫描原始表。

物化视图 (Materialized View) 的诞生 为了解决这个问题,物化视图应运而生。

核心思想:物化视图是一种预计算持久化存储的机制。它像一个“数据触发器”,当其监控的源表有新数据写入时,它会自动对这些新数据执行一个 SELECT 查询,并将结果**物化(存储)**到一个独立的目标表中。后续的查询可以直接访问这个小得多的、预聚合过的目标表,从而实现毫秒级的查询响应。

在 ClickHouse 中,物化视图的概念与其他数据库(如 Oracle, PostgreSQL)有本质区别。理解这一点至关重要。

ClickHouse 物化视图 = 触发器 (Trigger)

你可以把 ClickHouse 的物化视图理解为一个插入触发器。它本身不存储数据,它只是一个数据转换和搬运的规则

  1. 数据写入:当有 INSERT 操作将一批数据写入源表 (Source Table) 时。

  2. 触发执行:该 INSERT 操作会自动触发所有监听此源表的物化视图。

  3. 数据转换:物化视图执行其 AS SELECT ... 子句中定义的查询,但只针对刚刚插入的新数据块进行计算。

  4. 写入目标表:物化视图将转换后的结果集,以 INSERT 的方式写入到预先定义好的目标表 (Target Table) 中。

  5. 查询加速:用户查询时,直接查询这个已经预聚合过的、数据量小得多的目标表,而不是庞大的源表。

重要区别

  • 物化视图本身 (my_mv): 是一个没有数据的逻辑定义/触发器SELECT * FROM my_mv 通常是无意义的。

  • 目标表 (target_table): 是一个真实的、存储了预计算结果的物理表。我们最终查询的是它。

2 使用示例

场景:实时统计网站每分钟的页面浏览量(PV)和独立访客数(UV)。 

-- 存储原始访问日志
CREATE TABLE visits_raw
(`timestamp` DateTime,`url` String,`user_id` String
)
ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY (timestamp, url);INSERT INTO visits_raw (timestamp, url, user_id) VALUES
(now(), '/page/1', 'user-a'),
(now(), '/page/2', 'user-b'),
(now(), '/page/1', 'user-a'),
(now() + 2, '/page/3', 'user-c');

目标表用于存储预聚合的结果。这里的表引擎选择至关重要。对于聚合场景,AggregatingMergeTree 是最佳选择。

AggregatingMergeTree 引擎: 它专门用于增量聚合。它会将 SELECT 查询中带有 -State 后缀的聚合函数(如 countState, uniqState)的中间状态存储起来。在查询时,再使用 -Merge 后缀的函数(如 countMerge, uniqMerge)来完成最终计算。这使得后台合并和最终查询都极为高效。

-- 存储每分钟的 PV/UV 聚合结果
CREATE TABLE visits_agg_daily
(`minute` DateTime, -- 聚合时间粒度:分钟`pv` AggregateFunction(count), -- 存储 PV 的中间状态`uv` AggregateFunction(uniq, String) -- 存储 UV 的中间状态
)
ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMMDD(minute)
ORDER BY minute;

 现在,我们创建物化视图,将源表和目标表连接起来。

CREATE MATERIALIZED VIEW visits_mv TO visits_agg_daily -- 关键:指定数据流向的目标表
AS
SELECTtoStartOfMinute(timestamp) AS minute, -- 按分钟聚合countState() AS pv, -- 计算 PV 的中间状态uniqState(user_id) AS uv -- 计算 UV 的中间状态
FROMvisits_raw -- 关键:指定监听的源表
GROUP BYminute;

代码解析

  • TO visits_agg_daily: 明确指出,计算结果将写入 visits_agg_daily 表。

  • AS SELECT ... FROM visits_raw: 定义了转换逻辑。当 visits_raw 插入新数据时,就执行这个 SELECT

  • toStartOfMinute(timestamp): 将时间戳对齐到分钟级别。

  • countState(), uniqState(user_id): 使用 -State 函数,生成与 AggregatingMergeTree 兼容的聚合中间态。

  • GROUP BY minute: 按分钟进行聚合。

正确的查询方式

SELECTminute,countMerge(pv) AS page_views,uniqMerge(uv) AS unique_visitors
FROMvisits_agg_daily
GROUP BYminute
ORDER BYminute;

结果

minutepage_viewsunique_visitors
2023/11/20 10:3043

至此,我们成功搭建了一个全自动的实时聚合系统! 后续任何写入 visits_raw 的数据,都会被 visits_mv 自动处理并更新到 visits_agg_daily 中。分析查询只需要访问 visits_agg_daily 即可。物化视图只对创建之后新插入的数据生效。如果源表在创建物化视图之前就已经存在大量数据,怎么办?

使用 POPULATE 关键字!它会在创建视图的同时,将源表中的存量数据也进行一次转换并插入目标表。

CREATE MATERIALIZED VIEW visits_mv TO visits_agg_daily
POPULATE -- <<<<<<<<<<<<<<<<
AS
SELECT ...
  • AggregatingMergeTree: 最常用,适用于需要复杂聚合(如 uniq, avg, quantile)且要求高性能的场景。

  • SummingMergeTree: 如果你的聚合需求只有“求和”与“计数”,可以使用它。它会自动合并具有相同排序键的行,将度量列相加。比 AggregatingMergeTree 更简单。

  • 普通 MergeTree: 如果你不需要预聚合,只是想对数据进行ETL(比如清洗、转换、拆分列),可以将目标表设置为普通 MergeTree

  • 删除物化视图: DROP VIEW visits_mv;

    • 注意:删除物化视图不会删除目标表 visits_agg_daily。它只是切断了自动的数据流。目标表中的数据仍然存在。

  • 暂停/恢复:

    • DETACH TABLE visits_mv; 可以临时禁用物化视图。

    • ATTACH TABLE visits_mv; 可以重新激活它。

你可以创建一个物化视图,其目标表同时是另一个物化视图的源表,形成数据处理流水线(Pipeline)

  • MV1Source Table 读取数据,聚合后写入 a_min

  • MV2 监听 a_min,当 a_min 有新数据时,MV2 将其进一步聚合到 a_hour

总结

特性普通视图 (View)物化视图 (Materialized View)
存储数据否,只是查询别名否(本身是触发器),但其结果存储在物理目标表中
数据来源查询时实时计算源表 INSERT 时触发,增量计算
查询性能等同于其定义的复杂查询极高,直接查询预计算好的小表
数据新鲜度实时准实时(有微小延迟)
资源消耗查询时消耗大写入时有额外计算开销,查询时消耗小
核心作用简化复杂查询,权限控制查询加速,实时聚合,数据ETL

何时使用物化视图?

  1. 当你有高频的、固定的聚合查询,且无法接受直接扫描原始大表的延迟时。

  2. 当需要构建实时数据看板实时报表系统时。

  3. 当需要对写入的数据流进行持续的ETL转换时。

http://www.dtcms.com/a/298680.html

相关文章:

  • 学习笔记《区块链技术与应用》第二天 共识机制
  • 亚马逊阿联酋推“Amazon Bazaar”:解码中东电商市场的本地化突围
  • 线程安全的单例模式
  • 基于米尔瑞芯微RK3576开发板部署运行TinyMaix:超轻量级推理框架
  • 2025年高防IP全景解读:从流量清洗到智能防御的核心跃迁
  • mib2c --生成标量数据对应c文件
  • NOIP普及组系列【2015】 P2669 [NOIP 2015 普及组] 金币题解
  • GPU 驱动安装升级测试
  • 避开算力坑!无人机桥梁检测场景下YOLO模型选型指南
  • Minio Docker 集群部署
  • 【阅读整理】野火ADC_AD7192模块资料
  • haproxy七层代理(超详细)
  • 算法讲解--查找总价值为目标值的两个商品
  • MyBatisPlus简介与基本CRUD
  • 域名服务器的作用是什么
  • 【js(7)创建对象的三种写法】
  • Node.js(三)之Express
  • Three.js 动画系统入门:Tween.js 与 AnimationMixer 的使用
  • 习题5.6 “数学黑洞“
  • Java研学-RabbitMQ(二)
  • 亚德诺半导体AD8612ARUZ-REEL双通道精密运算放大器,0.5μV超低失调电压+0.02μV/°C温漂!
  • 老龄化浪潮下的破局者:智慧养老重塑银发经济格局
  • ptmalloc(glibc-2.12.1)源码解析2
  • 深入理解 UDP 协议:从原理到实战的技术解析
  • 开源语音TTS与ASR大模型选型指南(2025最新版)(疯聊AI提供)
  • Paimon主键表的合并机制
  • 模糊综合评估法简单示例
  • MySQL的认识与基本操作
  • NaVILA源码解析——从其VLA部分到其low-level部分:涵盖legged-loco、rsl_rl
  • AMD推出Radeon AI Pro R9700:32GB显存加持,发力AI推理与专业图形双场景