物化视图是PostgreSQL里被低估的利器。它解决了一个真实痛点:有些查询太贵,没法每次现算。比如一个仪表盘要关联多张表、聚合百万行数据、按客户算指标——每次请求都跑一遍,慢、贵、还不可预测。物化视图把结果存到磁盘,预计算一次,后续直接读存储的数据,查询瞬间变快。
但代价是数据会变旧。普通视图随源表自动更新,物化视图不会,必须手动刷新。问题从这里开始。
刷新听起来简单:REFRESH MATERIALIZED VIEW mv_ordersummary; 一行命令。但在生产环境,尤其是多租户、持续有流量的系统里,这行命令背后全是坑。
刷新可能耗时数分钟。操作会加锁。用户还在持续读取。一个租户的刷新失败不能拖垮其他租户。规模上来后,几十个甚至上百个物化视图在持续刷新,每个租户有自己的一套:mv_ordersummary_123、mv_ordersummary_456……
真正的难点不是创建物化视图,而是在流量不停的情况下,把旧数据换成新数据。
几个现实让这事变复杂:大数据集刷新耗时久;PostgreSQL刷新操作会获取锁;读者期待一致的结果;多租户放大运维问题;一个坏租户的刷新不能打断整个刷新周期。小规模时,默认的REFRESH MATERIALIZED VIEW够用。规模大了,你开始关心:锁持有多久、事务范围多大、膨胀问题、数据验证、可观测性、故障隔离、回滚安全。策略选择取决于你的负载特征。
先看工程师最常用的第一种方案:裸REFRESH MATERIALIZED VIEW。
这是最简单的选项。PostgreSQL原地重建物化视图内容,刷新期间获取ACCESS EXCLUSIVE锁——这把锁会阻塞读、写、并发刷新。读者只能等刷新完成。小数据集、低流量场景下没问题。但生产环境?这把锁就是噩梦的起点。
热门跟贴