6.1 物化视图


6.1 物化视图

本节摘要:5.4 的变式二留下了伏笔——当查询形态稳定却压无可压时,让系统记住计算结果。本节把这件事讲成一条决策链:先分清同步 Rollup 与异步物化视图两种托管方式各管哪段,再定刷新策略与时效承诺,最后用透明改写的四个命中条件验证投入是否生效。读完你应当不再手工维护任何一张聚合表。

学习目标

阅读完本节,你应当能够:

  1. 用"是否要求查询强实时"一个判断区分同步 Rollup 与异步物化视图的适用域;
  2. 为一个报表场景选定刷新策略并估算刷新开销;
  3. 背出透明改写的四个命中条件,并用执行计划验证改写是否发生;
  4. 识别三类预计算救不了的需求,及时止损转向建模手段。

一、两件容易混的事:同步与异步

Doris 里带"物化"字样的东西有两种,决策链的第一步就是别把它们混为一谈。同步 Rollup 挂在基表上,导入事务提交时同步更新,查询永远读到最新聚合——代价是每一次导入都要多做一遍聚合计算,写放大跟着聚合层数走。异步物化视图是一张独立的物理表,由后台任务按策略刷新,查询可能读到上一个刷新点的旧数据——代价是一致性延迟,换来的是导入链路零负担与更大的表达自由(可以是复杂表达式甚至多表关联,随版本演进能力不同)。

选择的分水岭就一个问题:业务能不能容忍聚合结果滞后于明细?大屏上的实时成交额,滞后一分钟都不行,走同步 Rollup 或者干脆优化基表;T+1 管理日报、小时级刷新的运营看板,滞后一个刷新周期毫无感知,异步物化视图是正解。多数团队的实际痛点集中在后者——报表的需求增长远快于导入吞吐的富余,写路径经不起同步聚合的持续抽税。

二、决策落地:一个报表集群的完整选择过程

拿一个真实场景走完链路。某 SaaS 客户成功团队有一张两亿行的事件明细表,运营侧固定消费三种口径:按天按套餐档位的活跃账号数、按周滚动的功能点击 TopN、按客户经理分组的三日留存。三条查询合计占集群白天查询量的四成,每条都在三到五秒徘徊。

第一步判断更新语义:事件明细只追加不修改,Duplicate 模型,无更新回填负担——预计算不会遭遇"刚算完就被改"的尴尬。第二步判断聚合可加性:账号数用去重计数、点击量用累加、留存本质是跨天去重交集——前两者可加,留存需要近似函数(HLL 族)承担。第三步定刷新节奏:事件数据从 Kafka 准实时落入,运营看板的数据延迟容忍度是十分钟。于是三张异步物化视图落成,其中一张的定义骨架如下:

CREATE MATERIALIZED VIEW mv_daily_active BUILD DEFERRED REFRESH AUTO ON SCHEDULE EVERY (10 MINUTES) START WITH '2026-08-28 00:00:00' AS SELECT dt, plan_tier, HLL_UNION(hll_hash(account_id)) AS active_users FROM dwd_user_event GROUP BY dt, plan_tier;

几个关键子句各有用意:BUILD DEFERRED 让创建动作不阻塞当下——两亿行的首次构建丢给后台慢慢算;REFRESH AUTO 把刷新时机交给调度器按十分钟的节奏自转;分区感知的增量计算保证每次只重算有新数据的分区,而不是对着两亿行全量重来。上线后三条查询的执行计划里先后出现了改写命中的注记,耗时从三五秒进入几百毫秒区间,白天查询量的四成被三个后台任务接管。

三、命中判定:改写为什么没发生

预计算投资最常见的失败形态是"建了但没吃到"。透明改写有四个命中条件,缺一不可:列覆盖——查询要的每一列视图里都有;谓词兼容——查询的过滤条件能推导到视图的分组维度上;聚合等价——视图的聚合粒度不粗于查询要求的粒度;分组一致——查询的分组列是视图分组列的子集。四个条件像一把四齿的梳子,任何一齿卡住,优化器都会礼貌地绕开视图回基表硬算。

排查有固定套路。先看执行计划:命中改写的计划里会出现物化视图的表名而非基表名,一眼定阴阳。未命中时逐条对梳子:最常见的卡齿是谓词里套了函数——视图按天分组,查询却写"最近七天"的相对时间函数,优化器推不出它与分区列的等价关系;第二常见是聚合函数不可加,查询要精确去重计数,视图里存的却是近似结构。把命中与否写进报表上线检查项,问题会在开发期暴露,而不是等运营问"为什么这个报表还是慢"。

图 6-1:一条查询穿过加速判定的四齿梳

图 6-1:一条查询穿过加速判定的四齿梳

四、边界与止损:预计算救不了的三类需求

把丑话说在前面。第一类,跨表关联的实时聚合。 物化视图的分区感知刷新继承基表分区策略,多表实时的联合预计算超出其能力边界——这类需求要么在导入链路里完成关联落成宽表(第 3 章的建模路线),要么等异步视图的多表能力版本落地再评估。第二类,秒级一致性的聚合。 异步刷新天然有延迟,要求"明细写入一秒后聚合可见"的场景,正确答案是优化基表扫描或用同步 Rollup 承接,别指望把刷新间隔调到秒级——那等于用后台任务模拟实时,调度开销先把你拖垮。第三类,口径频繁变更的报表。 视图定义即口径,口径每改一次就重建一次,两亿行的首次构建成本每次都要重付。口径动荡期的报表先跑基表,口径冻结后再固化视图。

止损的另一面是备份方案:物化视图的刷新任务失败会静默累积,看板读到的可能是三天前的旧聚合。把刷新任务的成功率纳入第 7 章的监控清单,并为关键视图配置"刷新超时告警"——预计算的信任建立很慢,砸掉只要一次数字对不上账。

常见疑问

问:物化视图会不会拖慢导入? 异步形态不会——刷新是独立的后台任务,与导入链路共享的只是集群资源。真正要防的是资源挤兑:刷新任务赶上导入洪峰时两者抢 IO,表现是双方都慢。把刷新调度避开导入高峰(错开五到十分钟常就足够),是零成本的最优解。

问:视图建多了怎么治理? 建立视图台账:每张视图登记服务对象(哪几张报表)、命中率、刷新耗时、存储占用四个字段,季度回顾时清理"零命中且占用高"的僵尸视图。物化视图是付费资产,没人消费的资产就是纯粹的负债。

问:视图的刷新失败会通知我吗? 默认不会——这正是本节反复强调把刷新任务纳入监控的原因。最低配置是给刷新任务的终态加一条采集:失败计数连续超过阈值即告警,并把"最后一次成功刷新时间"暴露给报表侧展示,让数据的时效能被消费者自己看见。

问:怎么估算一张视图值不值得建? 两个数字相乘再比较:每天被它接管的查询次数乘以单次节省的秒数,得到日收益;首次构建加每日刷新的耗时折算成资源占用,得到日成本。收益低于成本的候选直接放弃——判断做在创建之前,比建完再删体面得多。

本节要点回顾

  • 同步异步分水岭:能不能容忍聚合滞后,一个判断定方案。
  • 刷新策略跟着时效承诺走:十分钟看板配十分钟调度,别为不需要的实时付税。
  • 四齿梳验证投资:列覆盖、谓词兼容、聚合等价、分组一致,执行计划一眼定阴阳。
  • 三类需求及时止损:跨表实时、秒级一致、口径动荡,预计算不是万能筐。
  • 刷新任务要监控:静默失败的视图比没有视图更危险。

预计算解决了"本仓数据的消费成本",下一节转向另一头:数据根本不在本仓时,怎么不搬运就把查了。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U