1

I would like to do something like

results = select * from quick_table
if no results:
    insert into quick_table select slow_query
    results = select * from quick_table
return results

This is a pretty standard caching pattern. Is there any way I can do this in postgres that's more clever than just literally writing a function to do what I listed above?

4
  • So how will you handle concurrency? That'll probably shape the solution a lot... Commented May 16, 2021 at 4:07
  • Will you need cache invalidation, or just expiry? Commented May 16, 2021 at 4:09
  • 1
    @sabik Uniqueness constraint in quick_table. It's fine if slow_query runs multiple times, just inefficient Commented May 16, 2021 at 6:07
  • 1
    I don't need invalidation. I basically just want to see if the relevant row has been updated today, and if not update it Commented May 16, 2021 at 6:09

1 Answer 1

2

The PostgreSQL feature that comes closest to what you want to do is a materialized view.

This creates a copy on disk of the results of your view, which you can then query as if it were a table. You can also add indexes to it in the usual way.

A caveat is that when you generate a materialized view, its data does not update automatically when the source tables’ data change. To reflect changes, you must issue a REFRESH MATERIALIZED VIEW command.

Typical approaches to refreshing are:

  1. Run the refresh as a background task (e.g., in a cron job)
  2. Add triggers to the source tables such that changing data in them causes the view to refresh.

Each approach has advantages and disadvantages, so the route you take will depend on your circumstance. It may also be useful to make sure you can add a unique index to your MV, as that will allow you to run concurrent refreshes; without that, a refresh places an exclusive lock on the view, so it won’t be readable until the refresh has finished.

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

1 Comment

Thanks, but I don't think this is what I want. It can't transparently tell when it needs a refresh, and it would require me to refresh the entire table, not just stale rows

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.