38

I have a PostgreSQL DB, where I use materialized views. The problem occurs when I try to refresh these materialized views.

REFRESH MATERIALIZED VIEW product_cat_mview; REFRESH MATERIALIZED VIEW productsforproject; 

My solution is, when the user want to see updated data, he should click a "refresh button" on the web page, but this takes about 50s (on a local connection and about 2 minutes from the application server) and all this time the user has to wait, which is not good.

Now I should create a solution to automatically refresh these materialized views every 10 minutes. I have created a Java solution with multithreading. But I have one problem.

The first query

REFRESH MATERIALIZED VIEW CONCURRENTLY product_cat_mview; 

works correct, but the second

REFRESH MATERIALIZED VIEW CONCURRENTLY productsforproject; 

complains that I need to create a unique index. I tried create index, unique index etc. that I found in google, but I still get the message to "Create unique index".

2
  • Does this error get raised when you run the refreshes one by one? Commented Jan 23, 2017 at 10:42
  • I run them one by one with delay of 30 seconds. Commented Jan 23, 2017 at 10:49

1 Answer 1

61

You will have to create a unique index on the materialized view itself.

This would look like this:

CREATE UNIQUE INDEX ON productsforproject (id); 

Replace id with a suitable unique key column or a (comma separated) combination of such columns.

The reason for this requirement is that a concurrent refresh works different from a normal refresh: the query is executed, and the existing rows in the materialized view are updated or deleted or new rows inserted based on the query result. The unique index is required to identify which row in the materialized view should be updated or deleted.

Sign up to request clarification or add additional context in comments.

6 Comments

I have created this index. "CREATE UNIQUE INDEX ON productsforproject (barcode, materialdescription ASC);" But I have message : ERROR: cannot refresh materialized view "public.productsforproject" concurrently Hint: Create a unique index with no WHERE clause on one or more columns of the materialized view.
Maybe you need to specify the correct schema, like CREATE UNIQUE INDEX ON public.productsforproject .... Or you created it in the wrong database by mistake.
@LaurenzAlbe I added a unique index but when I try to refresh concurrently and query the materialized view - the query is stuck until the refresh ends. any idea?
Did you use CONCURRENTLY? Maybe open your own question for that and show the query, its execution plan and the contents of pg_locks while the refresh is running.
@FabriceChapuis That's not what happens with a concurrent refresh. The data in the materialized view are actually updated with the query results; hence the unique index.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.