更新日志:
1. 2020/06/16 group by 视图的部分描述错误,已修正。
什么是物化视图
我先用我的话解释一下什么是物化视图。假设我们已经有A,B两张表,现在我创建了一张表C,
C是由A,B两张表经过一条SQL处理得到的,这个时候我们就可以认为C是A,B的物化视图了。那怎么用呢?当一个用户写了一条使用A Join B表的SQL,系统会自动尝试能否改写成基于C表的查询,如果成功,那么可能查询速度就非常快了,因为避免了Join的发生,只是简单的基于C做了下过滤,但得到的结果和直接使用A,B 是一样的。
显然,物化视图有个很大的问题,就是更新问题,譬如A,B发生了变化,如何保证C 也得到更新。所以这里除了改写以外,还涉及到了C的创建,管理和更新问题。
现在让我们引入点术语了,前面我们提到的自动将基于A,B的查询改写成基于C的查询,我们叫Query Rewrite。Query Rewrite 就是将原有的查询不需要修改,引擎自动选择合适的物化视图进行查询重写,完全对应用透明。
物化视图和传统视图的最大的区别是,物化视图存储不仅存储了计算逻辑,还存储了计算结果,并且更进一步的是,作为用户你无需显示使用物化视图,系统会通过Query Rewrite自己来完成内部的改写。不过无论技术上多先进,我们最后都可以归纳到以空间换时间里去。
SQL Booster
今天我们探讨的重点是如何实现Query Rewrite。我去年写了一个Query Rewrite 引擎[s
ql-booster](https://github.com/aistack/sql-booster),其实是受到阿里李呈祥团队的relational cache启发。当时看了他们的分享觉得太棒了,很想立马就用,但是想着等他们推到开源项目里就太漫长了,加之目前大数据里的物化视图的实现,已经开源的貌似只有hive了,是基于Calcite实现的,而Spark 的话是自己开发的catlyst引擎,而我自己又重度使用Spark,所以干脆自己动手基于catalyst实现一个。后面在开发过程中也遇到了不少公司也在做类似的实现,也有问我的,可惜一直没有写文章,这次趁着周末,写了,既可以做为交流用,也可以作为备忘录。因为时间久了,代码和思路就很容易遗忘,文章可以很容易唤醒记忆,一箭双雕。
知识准备篇
一个物化视图由两部分构成:
1. 生成该物化视图的SQL
2. 表数据
表数据很简单,就是为了查询的。记录生成该物化视图的SQL的原因是,我们需要知道这个物化视图的数据是