Materialized View: SQL Queries on Steroids
dinesh.wiki
dinesh.wiki
Projects like https://readyset.io/, https://materialize.com/, https://github.com/mit-pdos/noria can keep your materialized views up to date as the underlying base tables change.
With the separate tools the idea is to stream the incoming updates and keep the materialized views up to date all the time.
https://jon.thesquareplanet.com/papers/phd-thesis.pdf
This is the paper on which Readyset and Noria are based.
I've mirrored the file here, this link should work for you: https://tazj.in/blobs/noria-thesis.pdf
It also rewrites queries to make use of any materialized views you have, if it would make the query more efficient without affecting the results (so covers some use cases which indices would cover)
https://cloud.google.com/bigquery/docs/materialized-views-in...
That way you can always go back in time. And storage is often cheap.
I read the timely dataflow which underpins materialize.com. It seems like we don’t necessarily need the support of loops, which timely dataflow allows, for regular SQL, which is a DAG of operators. It appears that as long as the database supports snapshot reads, one can have a push-based query execution to enable incremental MV updates. The problem, I think, is still in the write-amp-as-a-function-of-data, which is unbounded. It is very cool regardless.
The technique can be used for cache invalidation as well, given the data cached needs to be described in SQL, which seems reasonable.
How it is done:
1. Intermediate states of aggregate functions are first-class data types in ClickHouse. You can create a data type for the intermediate state of count(distinct), or quantile, whatever, and it will store a serialized state. It can be inserted into a table, read back, merged or finalized, and processed further.
2. Materialized views are simple triggers on INSERT. It enables incremental aggregation in realtime with materialized views.
Downsides:
Limited area of application. Does not respect multi-table queries if updates are done on more than one table.
Disclaimer: I'm developer of ClickHouse: https://github.com/ClickHouse/ClickHouse
SELECT AVG(col) FROM (SELECT MAX(col2) AS col FROM table GROUP BY col3) t;
type query? Essentially, materialized views which are very unstable? Flink has its retract streams where rows can be semantically removed from the output and downstream query plans can understand deletes, but my expectation has been that these have bad worst case performance.About the multi-level aggregate queries - the only way is to define a materialized view for the inner query and do calculations on top of it on the fly. So, the data for the inner query will be pre-aggregated, but nothing on top of that.
When I’ve used them the database has transparently handled updating them efficiently as the source data changes.
Caching the front page, server side, instead of rendering it on every request would have given similar result -- my guess. Specially when the query was taking 900ms.
Much easier to keep the cache located with the data since the cache changes when the data does.
One of my apps in fact use that table as primary (read) for most things and post the changes to the base tables. Was far faster than the normal way.
You might also be able to denormalize the categories down to an integer-array column and build a GIN or GiST index on that. I'd probably use triggers to automatically keep the integer-arrays up to date, but there are a number of ways it could be done if you don't like triggers.
It's a great tool, but also one that can easily become a source of its own problems. One big issue is that devs stop caring because "the materialized view is fast" and you end up with materialized views that take 20 minutes to generate, and thus are 20 mins out of date the moment they come online. I'm not being hyperbolic.
DB Normalization is good, but sometimes it brings its own problems. Sometimes duplication is "better". Sometimes you should ask yourself "is a document db like MongoDB a better solution for our needs?"