物化视图能将大表聚合查询从秒级降至毫秒级,因其预先计算并存储结果,避免每次查询重复执行join、group by等耗时操作,但需配合唯一索引与concurrently刷新才能在生产环境安全使用。

物化视图能绕过重复执行的开销
普通视图每次查询都得重跑整个 SELECT 语句,包括 JOIN、GROUP BY、窗口函数、子查询嵌套等——这些操作在大表上可能耗时数秒。而物化视图把结果存成物理表,SELECT * FROM mv_sales_summary 实际读的是已计算好的数据页,毫秒级返回。
常见错误现象:EXPLAIN ANALYZE 显示同一视图反复出现相同的高成本执行计划;pg_stat_statements 中该视图的 total_time 占比异常高。
- 适用场景:固定口径的报表(如按天/地区/品类聚合)、BI 看板底表、高频访问但逻辑不变的统计结果
- 性能影响:避免 CPU 和内存反复消耗在相同计算上,尤其当基表行数超千万、JOIN 超 3 张时优势明显
- 注意点:如果视图定义里含
NOW()、random()或用户变量,不能用于物化视图(PostgreSQL 会报错)
物化视图支持独立索引,普通视图不支持
你可以在 monthly_sales_mv 上直接建 CREATE INDEX idx_region_month ON monthly_sales_mv(region, month),而普通视图上建索引毫无意义——它没物理存储,索引无处落脚。
使用场景:当查询常带 WHERE region = '华东' AND month >= '2026-01' 这类过滤条件时,索引能让物化视图进一步加速,普通视图只能依赖基表索引,且 WHERE 下推常失败。
- 参数差异:
CONCURRENTLY刷新模式要求物化视图至少有一个唯一索引(否则报错cannot refresh concurrently without a unique index) - 容易踩的坑:忘记给物化视图加主键或唯一索引,导致无法用
CONCURRENTLY刷新,一刷新就锁死读请求
物化视图隔离 OLAP 查询与 OLTP 写入负载
查 orders 表的统计 SQL 可能扫描上亿行并持有共享锁较长时间;而查 mv_orders_summary 完全不碰基表,不会拖慢订单写入、库存扣减等核心事务。
PostgreSQL 18.4 官方 Ubuntu 安装包现已发布,这是目前最新的稳定版本。推荐通过官方 APT 仓库安装:先执行 sudo apt update 更新索引,再运行 sudo apt install postgresql-18 即可完成部署。新版本引入了异步 I/O 子系统,在顺序扫描与 VACUUM 场景下性能提升显著,同时支持 UUID v7 原生生成函数与虚拟生成列。
常见错误现象:业务高峰期 Dashboard 查询变慢,同时发现 pg_locks 中大量 AccessShareLock 持有者来自视图查询,阻塞了 UPDATE 事务。
- 兼容性影响:MySQL 原生不支持物化视图,强行模拟需用定时任务 + 普通表 +
TRUNCATE + INSERT SELECT,但缺乏原子性和并发安全机制 - 刷新策略选择:对延迟敏感的场景(如日结报表),用
pg_cron每日凌晨 2 点执行REFRESH MATERIALIZED VIEW CONCURRENTLY;对实时性要求低的(如周报),可手动触发
物化视图不是“银弹”,延迟和存储是硬代价
它的快,是以牺牲新鲜度和空间换来的。如果业务要求“下单后 1 秒内出现在销售看板”,物化视图就不合适——哪怕配置成每分钟刷新,也存在最多 60 秒延迟。
容易被忽略的地方:一张物化视图占用的磁盘空间可能接近甚至超过基表本身(尤其是含宽字段或未做分区裁剪时);频繁刷新还可能引发 WAL 日志暴涨,影响备份与流复制延迟。
真正关键的判断点不在“要不要用”,而在“能不能接受这个延迟 + 是否愿意承担刷新维护成本”。别只测查询快多少,一定要压测刷新过程本身:在业务低峰期执行一次 REFRESH MATERIALIZED VIEW CONCURRENTLY,观察持续时间、CPU/IO 尖峰、以及是否引发其他查询抖动。










