如何在PostgreSQL 15中使用SQL处理物化视图并发构建

云枫大大_8719

云枫大大_8719

2026-11-05

875人浏览

原创

PostgreSQL 15 中 CREATE MATERIALIZED VIEW 不支持 CONCURRENTLY,因其本质是单次 DDL 操作,需独占锁且无并发语义基础;仅 REFRESH 支持 CONCURRENTLY,但要求物化视图已存在、有 VALID 唯一索引且非空。

如何在postgresql 15中使用sql处理物化视图并发构建

PostgreSQL 15 中无法“并发构建”物化视图——CREATE MATERIALIZED VIEW 本身是单次、阻塞式操作,不支持 CONCURRENTLY 修饰;真正能并发执行的只有刷新动作:REFRESH MATERIALIZED VIEW CONCURRENTLY,但它要求物化视图已存在且满足严格前提。

为什么 CREATE MATERIALIZED VIEW 不支持 CONCURRENTLY

PostgreSQL 的物化视图创建过程本质是一次性 SELECT + INSERT INTO 新表,它不涉及“比对旧数据”,因此不存在并发安全问题的语义基础。官方语法明确排除了 CONCURRENTLY 选项——若强行加该关键字,会直接报错:ERROR: syntax error at or near "CONCURRENTLY"。

常见误解来源:把“并发刷新”(refresh)误记为“并发创建”(create)。两者在语义、实现机制和权限要求上完全隔离。

  • CREATE MATERIALIZED VIEW 是 DDL,需独占锁,但只在创建瞬间持有(通常几秒到几十秒,取决于源查询耗时)
  • REFRESH MATERIALIZED VIEW CONCURRENTLY 是 DML 风格操作,依赖唯一索引做行级差集比对,全程不锁整个视图
  • 试图用后台作业或多个连接同时执行 CREATE,只会触发序列化排队,不会提速,还可能因命名冲突失败

CREATE 后必须立刻建唯一索引才能用 CONCURRENTLY 刷新

刚建好的物化视图默认不可并发刷新,哪怕你已经确保 GROUP BY 字段业务上唯一。PostgreSQL 不推断、不信任业务逻辑,它只认显式创建的 UNIQUE INDEX。

典型错误流程:

CREATE MATERIALIZED VIEW mv_orders_daily AS
  SELECT DATE(order_time) AS day, COUNT(*) AS cnt
  FROM orders WHERE order_time >= '2026-01-01'
  GROUP BY DATE(order_time);
-- ✅ 创建成功
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_orders_daily;
-- ❌ 报错:ERROR: cannot refresh materialized view "mv_orders_daily" concurrently, because it does not have a unique index

修复只需两步(顺序不能颠倒):

  • 确认分组字段无 NULL:SELECT COUNT(*) FROM mv_orders_daily WHERE day IS NULL; → 必须为 0
  • 显式建唯一索引:CREATE UNIQUE INDEX idx_mv_orders_daily_day ON mv_orders_daily (day);
  • 索引状态需为 VALID:SELECT indexname, indisvalid FROM pg_indexes WHERE tablename = 'mv_orders_daily';

WITH NO DATA 创建后,CONCURRENTLY 刷新仍会失败

如果用 WITH NO DATA 创建物化视图(即只建结构、不填充),即使后续补了唯一索引,首次 REFRESH ... CONCURRENTLY 依然报错:cannot refresh ... concurrently because the materialized view is not populated。

原因:并发刷新机制依赖“已有数据”作为比对基准,空表无旧数据可比,无法执行差集逻辑。

正确做法只有两种:

  • 改用普通刷新启动:REFRESH MATERIALIZED VIEW mv_orders_daily;(会短暂锁表,但只一次)
  • 或创建时就用默认 WITH DATA(推荐),再立即建索引

没有“跳过首次全量”的捷径。试图绕过会导致后续所有并发刷新都不可用。

高频率刷新场景下,并发刷新反而更慢且易出错

当物化视图日增数据量超过总量 5%,或单次差异行数 > 10 万时,CONCURRENTLY 的差集计算开销(Hash Join + Sort + 两次索引扫描)会显著高于全量刷新。

典型症状:

  • REFRESH ... CONCURRENTLY 执行时间从 1 秒飙升至 30+ 秒
  • pg_stat_activity 显示大量 Hash Join 和 Sort 状态
  • 磁盘 I/O 持续满载,临时空间暴涨

此时应主动降级策略:

  • 改用非并发刷新:REFRESH MATERIALIZED VIEW mv_orders_daily;
  • 配合低峰期调度(如凌晨 2 点),用 pg_cron 或外部任务器触发
  • 刷新前先 ANALYZE mv_orders_daily;,避免统计信息陈旧导致计划退化

真正容易被忽略的是:并发刷新不是“性能优化开关”,而是“可用性保障开关”——它解决的是锁表阻塞问题,不是速度问题。是否启用,得看业务对查询中断的容忍度,而非单纯追求快。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
postgresql常用命令
postgresql常用命令

postgresql常用命令psql、createdb、dropdb、createuser、dropuser、\l、\c、\dt、\d table_name、\du、\i file_name、\e和\q等。本专题为大家提供postgresql相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.10

233

5

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4809

19

postgresql常用命令有哪些
postgresql常用命令有哪些

postgresql常用命令psql、createdb、dropdb、createuser、dropuser、\l、\c、\dt、\d table_name、\du、\i file_name、\e和\q等。更详细的postgresql常用命令,大家可以访问下面的文章。

2023.11.16

647

3

postgresql常用命令介绍
postgresql常用命令介绍

postgresql常用命令有\l、\d、\d5、\di、\ds、\dv、\df、\dn、\db、\dg、\dp、\c、\pset、show search_path、ALTER TABLE、INSERT INTO、UPDATE、DELETE FROM、SELECT等。想了解更多postgresql的相关内容,可以阅读本专题下面的文章。

2023.11.20

1396

6

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

2026.02.12

480

19

PostgreSQL 性能优化与查询执行计划实战
PostgreSQL 性能优化与查询执行计划实战

本专题深入解析PostgreSQL性能优化核心,聚焦查询执行计划的实战应用。通过EXPLAIN命令精准定位瓶颈,结合索引策略、SQL改写与参数调优,系统提升查询效率。从执行计划解读到性能调优全流程,助你掌握数据库性能诊断与优化实战能力。

2026.05.08

150

10

PostgreSQL 在 Next.js / Go 全栈架构中的工程化实践
PostgreSQL 在 Next.js / Go 全栈架构中的工程化实践

本文详解如何利用Next.js(搭配Drizzle ORM)与Go后端构建高性能应用,充分发挥PG在JSONB非结构化存储与pgvector向量检索上的优势。从数据建模到Docker容器化部署,打造支持AI时代的“One Database”工程化解决方案。

2026.05.08

901

10

PostgreSQL高级特性、内核机制与现代数据架构
PostgreSQL高级特性、内核机制与现代数据架构

本专题从MVCC并发控制与WAL日志等内核机制出发,详解JSONB、PostGIS及pgvector等高级特性。探讨如何利用单一引擎支撑关系型、向量及图数据等现代数据架构需求,助您掌握构建高并发、智能化应用的核心技术。

2026.05.08

244

10

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

2023.06.29

3025

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习