I have a feature I'm building that aggregates data across about a dozen or so tables. This data is aggregated from a heavily joined query. This page then has a lot of filtering, sorting, counting, and display options that need to work on top of this aggregated data set. There is one "global" condition/filter on the page so that it only loads data for the company viewing the page.
The site is built in Rails using Postgres as the database. Much of the filtering functionality is already built out using scopes on an ActiveRecord model of the aggregated data.
I've arrived at the following possible ways to solve this:
- Execute the full entire query each page load. This doesn't seem like a good approach because the entire query would need to be executed several times for things like different counts on the page
- Use a database view (or a materialized view). This works very well for the filtering, sorting, counting needs, but building the view is very slow since it has to look across the entire dataset and can't be scoped to just the account looking at the data. If I go with a materialized view, I have to manually update the view at different logical points in the app.
- Use a temp table. This would seem to have all the benefits of a view but load fairly fast since the temp table query would be scoped to just company viewing the page. The main problem is I haven't found a good way to have an ActiveRecord backed by a temp table (especially since the temp table query needs the context of which company is viewing)
- Use a physical table. This has the same advantages of a database view, except refreshing the table should be faster since the refresh process can execute just for a specific company' dataset.
I'm having a hard time weighing the pro's and con's of each approach. Is there anything I'm missing? Any other pros/cons or approaches to this?