《Everything you should know about materialized views.》 阅读笔记
原理
materialized views(以下简称MV)在insert的时候触发,并不会读源表,往一个表insert后,MV会从insert的数据中进行创建。 因此,源表甚至可以是个NULL Engine,即实际不写入数据,仅用来在inser时触发MV的动作。
MV的用途
- 用作聚合计算,如从原始表生成年、月、日、时的统计
- 用作触发器,使用NULL Engine,触发动作写入其他表
- 可以用来复制数据,如创建一个数据一致,但是排序不一致的表
MV的两种创建方式
TO
or .inner
.inner
方式:
inner表是一个实际的表,可以查看和插入数据
MV的一些理解误区
- MV的存储表并不知道MV的存在,也不知道原始表
- MV不会知道源表的合并、替换
- MV不知道源表的变更、删除、重命名等
- 往MV中的insert就是个普通的insert
- 这些存储表会按照自己的order、partition来做合并
- 如果是merge tree的机构,MV中的order by语句需要和group by一致,否则未order by的key被merge
- MV需要中的select需要有明确的列明,如
select a, d, count() as cnt ...
从一个表可以创建多个MV
- 往源表insert后,这个insert会按照字符串排序对每一个MV创建insert
- 有一个设置项:
parallel_view_processing
,开启后,在源表insert之后,会有多线程对多个MV进行更新
MV和源表数据不一致问题
deduplicate_blocks_in_dependent_materialized_views
设置项
不推荐使用join创建MV,CH使用HashJoin来对右侧的表创建hash,会耗费大量内存
Are Materialized Views inserted synchronously? 阅读笔记
- insert 发生时,数据会同时发往源表和MV
- insert 并不是原子操作, insert进行中时,客户端可能会有不缺定的结果,数据可能入了源表,但是MV失败,也可能是反过来
- 如果使用
async insert
,数据库会执行正常的insert,客户端可以使用wait_for_async_insert
来等待结果,如果成功的话, 就表明数据入到了源表和MV中 - 对于级联的MV,如果客户端如果得到了成功的结果,那么就表明数据已经入到了源表和所有的MV中