Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to partially refresh a materialized view in PostgreSQL?

In Oracle, it is possible to refresh just part of the data. But in PostgreSQL, materialized views are supported since 9.3 (the current version now), which is not so long. So I wonder: is it possible to refresh just part of the data in the materialized view in PostgreSQL 9.3? If yes, how to do it?

like image 633
Pavel V. Avatar asked Sep 03 '14 09:09

Pavel V.


People also ask

Can we alter materialized view in PostgreSQL?

To change a materialized view's schema, you must also have CREATE privilege on the new schema. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have CREATE privilege on the materialized view's schema.

How materialized view refresh works Postgres?

Parameters. Refresh the materialized view without locking out concurrent selects on the materialized view. Without this option a refresh which affects a lot of rows will tend to use fewer resources and complete more quickly, but could block other connections which are trying to read from the materialized view.

What are the various ways to trigger the refresh of materialized view?

create or replace TRIGGER REFRESH_REST_VIEW AFTER INSERT OR UPDATE ON tbl_contract BEGIN execute DBMS_MVIEW. REFRESH('REST_VIEW'); END REFRESH_REST_VIEW; commit; This is my sql trigger i am using to refresh Materialized View.

Can we refresh materialized view on timely basis?

Unlike indexes, materialized views are not automatically updated with every data change. They must explicitly be refreshed, either on every commit, on a periodically time schedule or – typically in data warehouses – at the end of an ETL job.


2 Answers

PostgreSQL doesn't support progressive / partial updates of materialized views yet.

9.4 adds REFRESH MATERIALIZED VIEW CONCURRENTLY but it still has to be regenerated entirely.

Hopefully we'll see support in 9.5 if someone's enthusiastic enough. It's only possible to do this without user-defined triggers/rules for simple materialized views though, and special support would be needed to even handle things like incremental update of a count(...) ... GROUP BY ....

The Oracle answer you refer to isn't actually incremental refresh, though. It's refresh by-partitions. For PostgreSQL to support that natively, it'd first have to support real declarative partitioning - which it doesn't, though we're discussing whether it can be done for 9.5.

like image 177
Craig Ringer Avatar answered Oct 17 '22 15:10

Craig Ringer


I just came across a similar problem. Learning from Craig's answer that it is not possible, I used a workaround. I deconstructed the materialized view and joined and/or unioned the individual parts in a VIEW:

  1. Create a MATERIALIZED VIEW for each row or column group in question (material_col1, material_col2, etc. or with more complex disjunct where conditions), using e.g. a common id column.
  2. Use a regular VIEW (fake_materialized_view) joining the MATERIALIZED VIEWs tables on the id column
    • in the case of disjunct rows one has to union all them
  3. REFRESH MATERIALIZED VIEW as needed
  4. Use your query on fake_materialized_view instead

The VIEW would look somewhat like this:

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

(Upd1: Thx to Barry for his comment utilizing row partitioning, which I added to the answer.)

like image 6
n1000 Avatar answered Oct 17 '22 15:10

n1000