物化视图是存储查询结果的物理表,普通视图仅保存SQL定义;前者查询快但需刷新、占存储、有延迟,后者实时但每次重计算、不占空间。

物化视图不是“高级视图”,它是把 SELECT 结果真真切切写进磁盘的一张表——查询时跳过解析、优化、执行全过程,直接读本地数据。
物化视图和普通视图到底差在哪
普通视图每次 SELECT 都重跑底层 SQL;物化视图只在刷新时计算一次,其余时间查的是物理存储的快照。
- 普通视图不占额外磁盘空间,物化视图会占用和它结果集相当的存储(比如聚合后只剩 10 万行,就存 10 万行)
- 普通视图实时反映基表变化,物化视图有延迟——取决于你用
REFRESH MATERIALIZED VIEW还是定时任务 - PostgreSQL 的
MATERIALIZED VIEW默认不可自动刷新;Oracle 可设ON COMMIT,但会拖慢写入;SLS(日志服务)支持透明改写+自动合并最新未物化数据
为什么加了物化视图,EXPLAIN 还显示 Seq Scan
不是语法错,是优化器根本没把它当候选对象——常见原因有三个:
- 查询里多写了列、改了别名、加了
WHERE谓词但不在物化视图定义范围内(比如物化视图只含month, region, SUM(amount),你却查WHERE status = 'paid') - 没建索引:物化视图本身是张表,但默认无任何索引。
CREATE INDEX idx_mv_month ON mv_sales_by_month (month);必须手动补上 - PostgreSQL 中需确保会话开启
SET enable_material = on;(虽然默认开启,但某些连接池或 ORM 会覆盖)
MySQL 用户别硬刚,换思路
MySQL 官方至今不支持 CREATE MATERIALIZED VIEW,强行模拟容易翻车:
- 用
CREATE TABLE AS SELECT ...+ 定时TRUNCATE + INSERT INTO ... SELECT是最常用替代方案,但要注意事务隔离与锁表风险 - 若基表更新频繁(如每秒百行订单),这种全量刷新会让延迟飙升,甚至阻塞业务写入
- 更稳妥的做法是:把聚合逻辑下沉到应用层缓存(Redis Hash / Sorted Set),或改用支持原生物化视图的引擎(如 Hologres、PostgreSQL、Oracle)
真正关键的不是“建没建”,而是“查没查上”——哪怕物化视图数据已就位,只要查询结构不匹配、索引缺失、或刷新滞后,它就只是个躺在磁盘上的静默文件。

















