ClickHouse性能优化?试试物化视图
一、前言
ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS);目前我们使用CH作为实时数仓用于统计分析,在做性能优化的时候使用了 物化视图
这一特性作为优化手段,本文主要分享物化视图的特性与如何使用它来优化ClickHouse的查询性能。
二、概念
数据库中的 视图(View)
指的是通过一张或多张表查询出来的 逻辑表 ,本身只是一段 SQL 的封装并 不存储数据。
而 物化视图(Materialized View)
与普通视图不同的地方在于它是一个查询结果的数据库对象(持久化存储),非常趋近于表;物化视图是数据库中的预计算逻辑+显式缓存,典型的空间换时间思路,所以用得好的话,它可以避免对基础表的频繁查询并复用结果,从而显著提升查询的性能。
在传统关系型数据库中,Oracle、PostgreSQL、SQL Server等都支持物化视图,而作为MPP数据库的ClickHouse也支持该特性。
三、ClickHouse物化视图
ClickHouse中的物化视图可以挂接在任意引擎的基础表上,而且会自动更新数据,它可以借助 MergeTree 家族引擎(SummingMergeTree、Aggregatingmergetree等),得到一个实时的预聚合,满足快速查询;但是对 更新 与 删除 操作支持并不好,更像是个插入触发器。
创建语法:
CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...
POPULATE 关键字决定了物化视图的更新策略:
- 若有POPULATE 则在创建视图的过程会将源表已经存在的数据一并导入,类似于 create table ... as
- 若无POPULATE 则物化视图在创建之后没有数据
ClickHouse 官方并不推荐使用populated,因为在创建视图过程中插入表中的数据并不会写入视图,会造成数据的丢失。
四、案例
4.1. 场景
假设有一个日志表 login_user_log
来记录每次登录的用户信息,现在需要按用户所属地为维度来统计每天的登录次数。
PS:这种 只有新增记录,没有更新删除的记录表就非常适合使用
物化视图
来优化统计性能
正常的聚合SQL如下:city为用户所属地,login_date为登录时间
select city, login_date, count(1) login_cnt
from login_user_log
group by city, login_date
增加 物化视图
后的架构如下图所示:
4.2. 建表
创建基础表:基础表使用 SummingMergeTree
引擎,进行预聚合处理
CREATE TABLE login_user_log_base
(
city String,
login_date Date,
login_cnt UInt32
)
ENGINE = SummingMergeTree()
ORDER BY (city, login_date)
SummingMergeTree表引擎主要用于只关心聚合后的数据,而不关心明细数据的场景,它能够在合并分区的时候按照预先定义的条件聚合汇总数据,将同一分组下的多行数据汇总到一行,可以显著的 减少存储空间并加快数据查询的速度。
创建物化视图:用户在创建物化视图时,通过 AS SELECT ...
子句从源表中查询需要的列,十分灵活
CREATE MATERIALIZED VIEW if not exists login_user_log_mv
TO login_user_log_base
AS
SELECT city, login_date, count(1) login_cnt
from login_user_log
group by city, login_date
使用 TO 关键字关联
物化视图
与基础表
,需要自己初始化历史数据。
4.3. 查询统计结果
使用物化视图查询
SELECT city, login_date, sum(login_cnt) cnt
from login_user_log_mv
group by city, login_date
注意:在使用物化视图(SummingMergeTree引擎)的时候,也需要按照聚合查询来写sql,因为虽然
SummingMergeTree
会自己预聚合,但是并不是实时的,具体执行聚合的时机并 不可控。
总结
- 在创建 MV 表时,一定要使用 TO 关键字为 MV 表指定存储位置,否则不支持 嵌套视图(多个物化视图继续聚合一个新的视图)
- 在创建 MV 表时如果用到了多表联查,不能为连接表指定别名,如果多个连接表中存在同名字段,在连接表的查询语句中使用 AS 将字段名区分开
- 在创建 MV 表时如果用到了多表联查,只有当第一个查询的表有数据插入时,这个 MV 才会被触发
- 在创建 MV 表时不要使用 POPULATE 关键字,而是在 MV 表建好之后将数据手动导入 MV 表
- 在使用 MV 的聚合引擎时,也需要按照聚合查询来写sql,因为聚合时机不可控
扫码关注有惊喜!
ClickHouse性能优化?试试物化视图的更多相关文章
- 详解Oracle数据货场中三种优化:分区、维度和物化视图
转 xiewmang 新浪博客 本文主要介绍了Oracle数据货场中的三种优化:对分区的优化.维度优化和物化视图的优化,并给出了详细的优化代码,希望对您有所帮助. 我们在做数据库的项目时,对数据货场的 ...
- HoloLens开发与性能优化实践
HoloLens中国版终于于5月底在中国上市,同时国内的技术社区经过一年的成长也有了很大的扩张,越来越多的开发者开始进入了HoloLens开发领域,尝试着使用混合现实(Mixed Reality)技术 ...
- MySQL · 性能优化 · 条件下推到物化表
MySQL · 性能优化 · 条件下推到物化表 http://mysql.taobao.org/monthly/2016/07/08/ 背景 MySQL引入了Materialization(物化)这一 ...
- Android应用性能优化系列视图篇——隐藏在资源图片中的内存杀手
图片加载性能优化永远是Android领域中一个无法绕过的话题,经过数年的发展,涌现了很多成熟的图片加载开源库,比如Fresco.Picasso.UIL等等,使得图片加载不再是一个头疼的问题,并且大幅降 ...
- clickhouse物化视图
今天来简单介绍一下clickhouse的物化视图 物化视图支持表引擎,数据保存形式由它的表引擎决定,创建物化视图的完整语法如下: create materialized view mv_log eng ...
- Oracle性能调优之物化视图用法简介
目录 一.物化视图简介 二.实践:创建物化视图 一.物化视图简介 物化视图分类 物化视图分类,物化视图语法和as后面的sql分为: (1) 基于主键的物化视图(主键物化视图) (2)基于Rowid的物 ...
- SQL Server索引视图以(物化视图)及索引视图与查询重写
本位出处:http://www.cnblogs.com/wy123/p/6041122.html 经常听Oracle的同学说起来物化视图,物化视图的作用之一就是可以实现查询重写,听起来有一种高大上的感 ...
- (转) Android开发性能优化简介
作者:贺小令 随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要求远远高于PC的桌面应用程序.以上理由,足以 ...
- 转载:SqlServer数据库性能优化详解
本文转载自:http://blog.csdn.net/andylaudotnet/article/details/1763573 性能调节的目的是通过将网络流通.磁盘 I/O 和 CPU 时间减到最小 ...
随机推荐
- DOM事件对象用法
分为三个阶段:事件捕获阶段.目标阶段.事件冒泡阶段. 事件捕获老版本浏览器(IE<=8)不支持,但是事件冒泡可以放心使用. 事件处理程序 一共四类写法,基本都见过,看下写法就知道怎么回事儿了. ...
- 教你玩转CSS Position(定位)
CSS Position(定位) position 属性指定了元素的定位类型. position 属性的五个值: static relative fixed absolute sticky 元素可以使 ...
- Github Action 快速上手指南
前言 各位读者,新年快乐,我是过了年匆忙赶回上海努力搬砖的蛮三刀. Github之前更新了一个Action功能(应该是很久以前了),可以实现很多自动化操作.用来替代用户自己设置的自动化脚本(比如:钩子 ...
- 图像仿射变换——MatLab代码实现
这里先说一下我们的目的,最近在用Pix2Pix 做一个项目的时候,遇到了成对图像质量差,存在着特征不能对齐的问题,即A图与B图是一组成对图像,我们想要将A 图中的物体转化为B 图中的物体,但这个物体在 ...
- .NET gRPC 核心功能初体验,附Demo源码
gRPC是高性能的RPC框架, 有效地用于服务通信(不管是数据中心内部还是跨数据中心). 由Google开源,目前是一个Cloud Native Computing Foundation(CNCF)孵 ...
- Redis缓存中的常见问题
缓存穿透:是指查询一个Redis和数据库中都不存在的数据. 问题:查询一个Redis和数据库中都不存在的数据,大量请求去访问数据库,导致数据库宕机. 解决办法: 1.根据id查询,如果id是自增的,将 ...
- golang知识总结
目录 1.slice扩容规则 2.内存寻址.内存对齐,go结构体内存对齐策略 3.go语言map类型分析 3.1 hash冲突 3.2 hash表扩容 3.3 go语言中的map结构是hash表. 3 ...
- MySQL注入流程
目录 确认注入点 信息收集 数据获取 提权 写个MySQL注入流程的大纲,类似一份全局地图,能指导下一步工作.MySQL注入流程分为四步: 确认注入点 信息收集 数据获取 提权 确认注入点 参考:ht ...
- 【Arduino学习笔记01】关于Arduino引脚的一些笔记
参考链接:https://www.yiboard.com/thread-831-1-1.html Arduino Uno R3 - 引脚图 Arduino Uno R3 - 详细参数 Arduino ...
- ElasticSearch(ES)使用Nested结构存储KV及聚合查询
自建博客地址:https://www.bytelife.net,欢迎访问! 本文为博客同步发表文章,为了更好的阅读体验,建议您移步至我的博客 本文作者: Jeffrey 本文链接: https://w ...