在PostgreSQL中,是否有可能对物化视图进行部分刷新?

27

在Oracle中,可以刷新部分数据。但是在PostgreSQL中,自9.3版本(当前版本)开始支持物化视图,这并不算太久。所以我想知道:在PostgreSQL 9.3中,是否可以刷新物化视图中的部分数据?如果可以,如何操作?


2
你能提供一个例子来说明你的意思吗?我认为使用物化视图的目的是仅显示部分数据。 - Lucas
你链接的那个针对Oracle的答案并不是很有说服力。它说你可以强制替换其中一个分区为分区MV。由于在PostgreSQL中分区并不是真正的内置功能,而是需要自己实现的东西,我想你也可以在Postgres中采用同样的方法。 - Thilo
2个回答

30

目前,PostgreSQL不支持材料化视图的渐进/部分更新。

9.4版本新增了REFRESH MATERIALIZED VIEW CONCURRENTLY,但它仍然需要完全重新生成。

希望如果有人充满热情的话,我们会在9.5中看到支持。只有对于简单的材料化视图而言,才能够不使用用户定义的触发器/规则进行此操作,而且即使处理像增量更新 count(...) ... GROUP BY ... 这样的内容也需要特殊支持。

你所提到的Oracle解决方案实际上并非增量刷新。 它是按分区刷新。 为了让PostgreSQL原生支持它,它首先必须支持真正的声明式分区 - 而它目前没有这个功能,尽管我们正在讨论是否可以在9.5中实现。


值得一提的是,正在开发中的新功能是:https://wiki.postgresql.org/wiki/Incremental_View_Maintenance。 - acristu
4
这个回答是否仍适用于14.5版本? - PirateApp
2
是的,不幸的是,看起来仍然是全有或全无。根据我下面链接的文档“REFRESH MATERIALIZED VIEW完全替换了物化视图的内容。”请参见https://www.postgresql.org/docs/current/sql-refreshmaterializedview.html - Shmuel Kamensky

6
我刚遇到了类似的问题。从Craig's answer中学到不可能后,我使用了一种变通方法。我拆分了物化视图并在VIEW中连接和/或联合了单个部分:
  1. 为每个涉及的行或列组(material_col1material_col2等)创建一个MATERIALIZED VIEW,例如使用共同的id列。
  2. 使用常规的VIEW (fake_materialized_view) 连接这些MATERIALIZED VIEW表,连接条件为id列。
    • 对于不连续的行,必须将它们全部union all
  3. 根据需要REFRESH MATERIALIZED VIEW
  4. 使用你的查询在fake_materialized_view
VIEW看起来会像这样:
CREATE VIEW fake_materialized_view AS 

  SELECT m1.id, m1.col1, m2.col2
  FROM material_col1 as m1 LEFT JOIN 
       material_col2 as m2 
         ON m1.id = m2.id

  -- in case of additional row partitioning, e.g.
  -- UNION ALL SELECT m3.id, m3.col1, m3.col2
  -- FROM material_col3 m3

(更新1:感谢Barry使用行分区的评论,我已将其添加到答案中。)


2
不幸的是,这只对“分区列”有用,而不适用于“分区行”(它们不一定映射到简单可定义的分区,而是映射到单个行)。 - Andreas Covidiot
1
@AndreasDietrich 如果分区列表相对固定,则在每个分区上使用一个物化视图的union all可以正常工作。它不会在每种情况下都有帮助,但对于聚合的物化视图来说,它可以很好地工作。 - Barry Kelly
@n1000:嘿,我刚意识到我编辑了你的回答,我以为那是我的:/...如果我的编辑不合适,对不起...那我们就还原它,我会发布一个带有示例的单独回答。 - Andreas Covidiot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接