ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS);目前咱们使用CH做为实时数仓用于统计分析,在作性能优化的时候使用了 物化视图
这一特性做为优化手段,本文主要分享物化视图的特性与如何使用它来优化ClickHouse的查询性能。sql
数据库中的 视图(View)
指的是经过一张或多张表查询出来的 逻辑表 ,自己只是一段 SQL 的封装并 不存储数据。数据库
而 物化视图(Materialized View)
与普通视图不一样的地方在于它是一个查询结果的数据库对象(持久化存储),很是趋近于表;物化视图是数据库中的预计算逻辑+显式缓存,典型的空间换时间思路,因此用得好的话,它能够避免对基础表的频繁查询并复用结果,从而显著提高查询的性能。缓存
在传统关系型数据库中,Oracle、PostgreSQL、SQL Server等都支持物化视图,而做为MPP数据库的ClickHouse也支持该特性。性能优化
ClickHouse中的物化视图能够挂接在任意引擎的基础表上,并且会自动更新数据,它能够借助 MergeTree 家族引擎(SummingMergeTree、Aggregatingmergetree等),获得一个实时的预聚合,知足快速查询;可是对 更新 与 删除 操做支持并很差,更像是个插入触发器。架构
建立语法:性能
CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...
POPULATE 关键字决定了物化视图的更新策略:优化
ClickHouse 官方并不推荐使用populated,由于在建立视图过程当中插入表中的数据并不会写入视图,会形成数据的丢失。
假设有一个日志表 login_user_log
来记录每次登陆的用户信息,如今须要按用户所属地为维度来统计天天的登陆次数。spa
PS:这种
只有新增记录,没有更新删除的记录表就很是适合使用
物化视图
来优化统计性能
正常的聚合SQL以下:city为用户所属地,login_date为登陆时间日志
select city, login_date, count(1) login_cnt from login_user_log group by city, login_date
增长 物化视图
后的架构以下图所示:code
建立基础表:基础表使用 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 关键字关联物化视图
与基础表
,须要本身初始化历史数据。
使用物化视图查询
SELECT city, login_date, sum(login_cnt) cnt from login_user_log_mv group by city, login_date
注意:在使用物化视图(SummingMergeTree引擎)的时候,也须要按照聚合查询来写sql,由于虽然
SummingMergeTree
会本身预聚合,可是并非实时的,具体执行聚合的时机并
不可控。
扫码关注有惊喜!