我对PostgreSQL 9.3数据库有一个materialized 视图,它很少更改(大约每天两次).但当它这样做时,我想及时更新它的数据.

以下是我到目前为止的 idea :

有一个materialized 视图mat_view,它使用一些join语句从表table1table2获取数据.

每当table1table2中的某些内容发生变化时,我已经有了一个触发器,它会更新一个小的配置表config,其中包括

table_name | mat_view_name | need_update
-----------+---------------+------------
table1     | mat_view      | TRUE/FALSE
table2     | mat_view      | TRUE/FALSE

因此,如果table1中的任何内容发生变化(每个语句都有一个UPDATE和DELETE触发器),则第一行的字段need_update设置为TRUE.

显然,如果need_update为真,则必须刷新materialized 视图.

UPDATE:

  • 判断是否应更新mat_view(SELECT 1 FROM config WHERE mat_view_name='mat_view' AND need_update=TRUE)
  • need_update标志重置为UPDATE config SET need_update=FALSE where mat_view_name='mat_view'
  • REFRESH MATERIALIZED VIEW mat_view
  • 最后执行最初的SELECT语句,但目标为mat_view.

UPDATE2:

创建一个处理上述四点的函数:

CREATE OR REPLACE FUNCTION mat_view_selector()
RETURNS SETOF mat_view AS $body$
BEGIN
  -- here is checking whether to refresh the mat_view
  -- then return the select:
  RETURN QUERY SELECT * FROM mat_view;
END;
$body$ LANGUAGE plpgsql;

创建真正从函数mat_view_selector中 Select 的视图v_mat_view:

CREATE TABLE v_mat_view AS SELECT * from mat_view LIMIT 1;
DELETE FROM v_mat_view;

CREATE RULE "_RETURN" AS
    ON SELECT TO v_mat_view
    DO INSTEAD 
        SELECT * FROM mat_view_selector();
    -- this also converts the empty table 'v_mat_view' into a view.

结果令人不满意:

# explain analyze select field1 from v_mat_view where field2 = 44;
QUERY PLAN
Function Scan on mat_view_selector (cost=0.25..12.75 rows=5 width=4)
(actual time=15.457..18.048 rows=1 loops=1)
Filter: (field2 = 44)
Rows Removed by Filter: 20021
Total runtime: 31.753 ms

与从mat_视图本身 Select 相比:

# explain analyze select field1 from mat_view where field2 = 44;
QUERY PLAN
Index Scan using mat_view_field2 on mat_view (cost=0.29..8.30 rows=1 width=4)
  (actual time=0.015..0.016 rows=1 loops=1)
Index Cond: (field2 = 44)
Total runtime: 0.036 ms

所以从本质上讲,它确实有效,但性能可能是一个问题.

有谁有更好的主意吗?

推荐答案

PostgreSQL 9.4在materialized 视图中添加了REFRESH CONCURRENTLY个.

当您描述试图设置materialized 视图的异步更新时,这可能就是您想要的.

在刷新完成之前,从materialized 视图中 Select 的用户将看到不正确的数据,但在许多使用materialized 视图的场景中,这是一个可接受的折衷方案.

使用语句级触发器,监视基础表的任何更改,然后同时刷新materialized 视图.

Postgresql相关问答推荐

Trunc函数不删除小数

横向联接返回的行数太多

ANTLR4 PostgreSQL语法被 destruct 了吗?

从数据集中提取彼此喜欢的用户(&Q;)

Postgres:创建分区需要很长时间

我应该如何更新热门表?

Postgres数据库系统已准备好接受连接和docker compose

Supabase 数据库大小问题

在 to_tsquery 中转义特殊字符

在 postgres 中Decode解码相似的函数

并发刷新materialized视图

如何在构建时链接 docker 容器?

PostgreSQL:如何安装 plpythonu 扩展

在 PL/pgSQL 中声明行类型变量

django.db.utils.IntegrityError:duplicate key value violates unique constraint "django_content_type_pkey"

在 postgresql 中,如何在 jsonb 键上返回布尔值而不是字符串?

如何在 postgres 模式中列出关系

如何判断 PostgreSQL 事务中的待处理操作

pgadmin 错误:no password supplied

在 Postgres 9.0+ 中使用 PL/pgSQL 在表上循环