Skip to content

Instantly share code, notes, and snippets.

@samuelreh
Last active November 28, 2023 12:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samuelreh/9770b2536b615a72d235 to your computer and use it in GitHub Desktop.
Save samuelreh/9770b2536b615a72d235 to your computer and use it in GitHub Desktop.
Refresh Materialized View Concurrently(ish) in Postgres 9.3

Refresh Materialized View Concurrently(ish) in Postgres 9.3

Recenlty at Attribution, we've been implementing materiazlied views to speed up slow queries. Although the concept is nothing new, and Materialized Views have been a feature of Oracle for years. They're a new feature in Postgres 9.3.

One missing piece in 9.3 is the ability to refresh views concurrantly, without exclusivly locking the whole view. Postgres 9.4 introduces this feature, which is great if you manage your own DB. However, those of us that use hosted database solutions, such as Amazon RDS, are not so lucky.

So we were faced with a couple options:

  • Hold off on materizlied views until 9.4 is available for RDS,
  • Move DB providers to something that supports 9.4, or
  • Hack something together.

We chose the latter of course. Our solution: to copy the view (which is pretty quick) and swap it out for the copied version while we refresh the view. Here's a sample of the SQL (our view is called 'visitors'):

CREATE TABLE visitors_copy AS (select * from visitors);

BEGIN;
  ALTER MATERIALIZED VIEW visitors RENAME TO visitors_refreshing;
  ALTER TABLE visitors_copy RENAME TO visitors;
COMMIT;

REFRESH MATERIALIZED VIEW visitors_refreshing;

BEGIN;
  DROP TABLE visitors;
  ALTER MATERIALIZED VIEW visitors_refreshing RENAME TO visitors;
COMMIT;

Now, wherever we would normally call REFRESH MATERIALIZED VIEW, we run the script. Although, it doesn't copy over the indecies on the materialized view, I don't think that would be hard to add on.

We're pretty sure this will hold us off until RDS supports Postgres 9.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment