《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中