19.物化视图和普通视图
物化视图和普通视图
目录
物化视图和普通视图最核心的区别在于:普通视图是“虚拟表”,而物化视图是“快照表”。
在PostgreSQL中,WITH NO DATA 语法只适用于物化视图(Materialized View),不适用于普通视图。普通视图没有存储数据,所以不需要这个选项。
普通视图 vs 物化视图对比
| 维度 | 普通视图 | 物化视图 |
|---|---|---|
| 存储内容 | 不存储数据,仅存储查询(SELECT)语句的定义。 | 物理存储数据,将查询结果像普通表一样持久化到磁盘上。 |
| 数据实时性 | 动态/实时。每次查询时,都实时执行其背后的SQL,返回当前最新数据。 | 静态/非实时。存储的是创建或最后一次刷新时的数据快照。 |
| 刷新机制 | 无需刷新,查询即刷新。 | 需要手动或定期刷新(REFRESH MATERIALIZED VIEW)以更新数据。 |
| 查询性能 | 通常较慢。尤其是视图定义复杂时,每次查询都是一次完整计算。 | 极快。因为查询的是预计算、已存储的数据,类似查表。 |
| 资源消耗 | 每次查询消耗CPU和I/O。 | 刷新时消耗大量CPU、I/O和存储空间;查询时消耗极低。 |
使用建议
- 普通视图适合数据量小、查询简单、需要实时数据的场景
- 普通视图:只是保存的查询语句,不存储数据,每次查询时动态执行
- 物化视图:物理存储查询结果,需要刷新才能更新数据
- 物化视图适合数据量大、查询复杂、可接受一定延迟的报表类场景
如何选择?从应用场景看本质
理解了核心区别后,你可以通过它们最典型的应用场景来做选择:
1. 何时使用普通视图?—— 简化与安全
普通视图的核心是 “简化复杂查询” 和 “实现数据安全与抽象”。
- 1.简化查询:将频繁使用的复杂JOIN、聚合查询封装成一个视图,方便应用调用,避免重复编写复杂SQL。
- 2.数据安全:通过视图只暴露部分行(如WHERE dept_id = 当前用户部门)或部分列,隐藏敏感数据。
- 3.逻辑抽象:为复杂的表结构提供一个清晰、统一的业务接口。
- 4.实时性要求高:业务需要随时看到最新数据,如订单详情页、实时库存查询。
2. 何时使用物化视图?—— 性能与聚合
物化视图的核心是 “用空间换时间”,牺牲一定的数据实时性来换取极致的查询性能。
- 1.加速复杂报表:针对涉及多表JOIN和大数据量聚合的复杂分析查询,将其结果预计算存储,使报表查询毫秒级返回。
- 2.数据仓库/OLAP:是构建数据仓库层和数据集市的关键组件,用于预聚合不同维度的指标。
- 3.连接远程数据库:在PostgreSQL中,物化视图可以缓存来自外部数据源(如另一个数据库)的查询结果,避免每次都进行昂贵的远程查询。
- 4.数据定期同步快照:需要非实时、定期一致的数据副本用于分析或特定业务。
💡 重要注意事项与最佳实践
刷新成本:刷新一个大型的、复杂的物化视图可能非常耗时,并会给源表带来负载。通常安排在业务低峰期(如凌晨)进行。
数据延迟:业务必须能容忍数据“不是最新的”。例如,用于每日经营分析看板的物化视图,延迟几小时通常可以接受;但绝不能用于实时交易系统。
物化视图的刷新方式:
全量刷新:REFRESH MATERIALIZED VIEW ... 会从头重新计算,会锁定视图(在刷新期间通常不可查询)。
增量刷新:REFRESH MATERIALIZED VIEW CONCURRENTLY ... 允许在刷新时同时查询,但需要视图上存在唯一索引。
索引:可以为物化视图创建索引,就像对普通表一样,这能进一步提升查询速度。
实践建议:一个决策场景
场景:CEO需要查看公司每日销售总额和Top 10商品。
- 方案一(普通视图):创建一个daily_sales_summary视图。CEO每次打开看板时,系统都会实时去扫描数百万条销售记录并聚合。CEO可能需要等待十几秒,且会拖慢生产数据库。
- 方案二(物化视图):创建一个同名的物化视图,并设置每天凌晨2点全量刷新。CEO白天查询时,数据是截至凌晨2点的快照,但查询结果瞬间返回,且不影响白天生产系统的性能。
结论:这是一个典型的“用物化视图进行性能优化”的场景。
总而言之,普通视图是逻辑封装和实时访问的工具,而物化视图是性能优化和数据预聚合的利器。根据你对数据实时性和查询性能的需求,做出合适的选择即可。如果你的业务场景对两者有混合需求,也可以同时使用它们。

浙公网安备 33010602011771号