Clickhouse学习笔记(12)—— 物化视图

ClickHouse 的物化视图是一种查询结果的持久化,与普通视图对比,其不仅保存了查询的逻辑,还保存了查询结果;

物化视图与普通视图的区别

普通视图不保存数据,保存的仅仅是查询语句,查询的时候还是从原表读取数据 ,可以将普通视图理解为是个子查询

物化视图则是把查询的结果根据相应的引擎存入到了磁盘或内存中 ,对数据重新进行了组织,可以理解物化视图是完全的一张新表

物化视图的优缺点

  1. 优点:查询速度快,因为提前进行了预计算
  2. 缺点:
    1. 不适用于使用历史数据的场景,因为物化视图的本质是一个流式数据的使用场景,是累加式的技术
    2. 如果一张表加了好多物化视图,在写这张表的时候,就会消耗很多机器的资源

物化视图建表语法

CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...

[MATERIALIZED] VIEW:物化视图

[TO[db.]name] :物化视图创建一个隐藏的目标表来保存视图数据;也可以 TO 表名,保存到一张显式的表;没有加 TO 表名,表名默认就是 .inner.物化视图名

创建物化视图的限制

1.必须指定物化视图的 engine 用于数据存储

2.TO [db].[table]语法的时候,不得使用 POPULATE。

3.查询语句(select)可以包含下面的子句: DISTINCT, GROUP BY, ORDER BY, LIMIT...

4.物化视图的 alter 操作有些限制,操作起来不大方便。

5.若物化视图的定义使用了 TO [db.]name 子语句,则可以将目标表的视图 卸载

DETACH 再装载 ATTACH

物化视图的数据更新策略

(1)物化视图创建好之后,若源表被写入新数据则物化视图也会同步更新

(2)POPULATE 关键字决定了物化视图的更新策略:

若有 POPULATE 则在创建视图的过程会将源表已经存在的数据一并导入,类似于create table ... as

若无 POPULATE 则物化视图在创建之后没有数据,只会在创建只有同步之后写入源表的数据

clickhouse 官方并不推荐使用 POPULATE,因为在创建物化视图的过程中同时写入的数据不能被插入物化视图。

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

测试

建表hits_test

sql 复制代码
CREATE TABLE hits_test
(
 EventDate Date, 
 CounterID UInt32, 
 UserID UInt64, 
 URL String, 
 Income UInt8
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(EventDate)
ORDER BY (CounterID, EventDate, intHash32(UserID))
SAMPLE BY intHash32(UserID)
SETTINGS index_granularity = 8192

导入数据:

sql 复制代码
INSERT INTO hits_test 
 SELECT 
 EventDate,
 CounterID,
 UserID,
 URL,
 Income 
FROM hits_v1 
limit 10000;

创建物化视图:

sql 复制代码
CREATE MATERIALIZED VIEW hits_mv 
ENGINE=SummingMergeTree()
PARTITION BY toYYYYMM(EventDate) 
ORDER BY (EventDate, intHash32(UserID)) 

AS SELECT
UserID,
EventDate,
count(URL) as ClickCount,
sum(Income) AS IncomeSum
FROM hits_test
WHERE EventDate >= '2014-03-20'
GROUP BY UserID,EventDate;

通过WHERE EventDate >= '2014-03-20'来设置更新点,该时间点之前的数据可以通过insert手动导入

创建成功后可以看到视图与其对应的内部表:

此时无论查询视图(select * from hits_mv;)或者内部表(select * from `.inner.hits_mv`;)均没有数据,因为数据导入实在视图创建之前;

接下来导入增量数据:

sql 复制代码
INSERT INTO hits_test 
SELECT 
 EventDate,
 CounterID,
 UserID,
 URL,
 Income 
FROM hits_v1 
WHERE EventDate >= '2014-03-23' 
limit 10;

查询视图即可看到数据:

如果想要导入历史数据,通过EventDate条件即可实现,例如:

sql 复制代码
INSERT INTO hits_mv
SELECT
 UserID,
 EventDate,
 count(URL) as ClickCount,
 sum(Income) AS IncomeSum
FROM hits_test
WHERE EventDate = '2014-03-20'
GROUP BY UserID,EventDate
相关推荐
企鹅侠客2 分钟前
ETCD调优
数据库·etcd
Json_181790144808 分钟前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
大数据编程之光14 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
B站计算机毕业设计超人16 分钟前
计算机毕业设计SparkStreaming+Kafka旅游推荐系统 旅游景点客流量预测 旅游可视化 旅游大数据 Hive数据仓库 机器学习 深度学习
大数据·数据仓库·hadoop·python·kafka·课程设计·数据可视化
煎饼小狗20 分钟前
Redis五大基本类型——Zset有序集合命令详解(命令用法详解+思维导图详解)
数据库·redis·缓存
风尚云网31 分钟前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
永乐春秋36 分钟前
WEB-通用漏洞&SQL注入&CTF&二次&堆叠&DNS带外
数据库·sql
熙曦Sakura1 小时前
完全竞争市场
笔记
打鱼又晒网1 小时前
【MySQL】数据库精细化讲解:内置函数知识穿透与深度学习解析
数据库·mysql
大白要努力!1 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle