|
|
|
|
|
by ericHosick
1705 days ago
|
|
> Still hoping for those automatically refreshed materialized views in PostgreSQL, ala what VoltDB has. Not exactly what you're hoping for and you probably already follow this pattern. pg_cron can help (and is now available in AWS RDS). ```sql
CREATE EXTENSION IF NOT EXISTS pg_cron; CREATE MATERIALIZED VIEW IF NOT EXISTS activeschema.some_thing_cached AS ...; SELECT cron.schedule('some_thing_cached', '/5 * * *',
$CRON$ REFRESH MATERIALIZED VIEW some_thing_cached; $CRON$
);
``` |
|
I don't know much about how postgresql works internally, so I just probably don't understand the constraints. Anyway as I understand, there are two ways to refresh. You either refresh a view concurrently or not.
If not, then postgres rebuilds the view from its definition on the side and at the end some internal structures are switched from the old to the new query result. Seems reasonable, but for some reason, which I don't understand due to my limited knowledge, an exclusive access lock is held for the entire duration of the refresh and all read queries are blocked, what doesn't work for us.
If you refresh concurrently, postgres rebuilds the view from its definition and compares the old and the new query result with a full outer join to compute a diff. The diff is then applied to the old data (like regular table INSERT/UPDATE/DELETE I assume), so I think you get away with just an exclusive lock and read access still works. There are two downsides to this, first that it requires a UNIQUE constraint for the join, second that the full outer join is a lot of additional work.
I never had the time to test Materialize, but it seems to do what I want with its continuous refresh.
I also thought about splitting the materialized view into two, one for rarely changing data and another one for smaller part of the data which changes daily. Then I would only have to refresh the smaller view and UNION ALL both materialized views in a regular view. Not sure how well will that work with postgres query planner.