CREATE MATERIALIZED VIEW
Materialized View support is in beta.
It may not be fit for production use.
To enable beta materialized views, set cairo.mat.view.enabled=true
in
server.conf
, or export the equivalent environment variable:
QDB_CAIRO_MAT_VIEW_ENABLED=true
.
Please let us know if you run into issues.
Either:
- Email us at support@questdb.io
- Join our public Slack
- Post on our Discourse community
To create a new materialized view in the database, use the
CREATE MATERIALIZED VIEW
keywords followed by the query that defines the
materialized view.
A materialized view holds the result set of the given query, and is automatically refreshed and persisted. For more information on the concept, see the reference on materialized views.
Syntax
To create a materialized view, manually enter the parameters and settings:
Metadata
To check materialized view metadata, use the materialized_views()
function,
which is described in the meta functions
documentation page.
The following example demonstrate creating materialized views from basic statements, and introduces feature such as partitioning.
Creating a view
Our examples use the following base table:
CREATE TABLE trades (
timestamp TIMESTAMP,
symbol SYMBOL,
price DOUBLE,
amount DOUBLE
) TIMESTAMP(timestamp)
PARTITION BY DAY;
Now we can create a materialized view holding aggregated data from the base table:
CREATE MATERIALIZED VIEW trades_hourly_prices AS (
SELECT
timestamp,
symbol,
avg(price) AS avg_price
FROM trades
SAMPLE BY 1h
) PARTITION BY HOUR;
Now, we've created a materialized view that will be automatically refreshed each
time when the base table (trades
) gets new data.
The refreshes are incremental. The view data is populated partially, and only for the changed parts of the base table.
Queries supported by incrementally refreshed materialized views are limited to
SAMPLE BY
queries without FROM-TO
and FILL
clauses, and GROUP BY
queries
with the designated timestamp as the grouping key.
Base table
Incrementally refreshed views require that the base table is specified, so that the server refreshes the materialized view each time the base table is updated. When creating a materialized view that queries multiple tables, you must specify one of them as the base table.
CREATE MATERIALIZED VIEW trades_ext_hourly_prices
WITH BASE trades
AS (
SELECT
t.timestamp,
t.symbol,
avg(t.price) AS avg_price,
avg(e.price) AS avg_ext_price
FROM trades t
LT JOIN ext_trades e ON (symbol)
SAMPLE BY 1d
) PARTITION BY WEEK;
Partitioning
PARTITION BY
allows for specifying the
partitioning strategy for the materialized view.
Materialized views can be partitioned by one of the following:
YEAR
MONTH
WEEK
DAY
HOUR
The partitioning strategy cannot be changed after the materialized view has been created.
Time To Live (TTL)
A retention policy can be set on the materialized view, bounding how much data is stored.
Simply specify a time-to-live (TTL) using the TTL
clause, placing it right
after PARTITION BY <unit>
.
Follow the TTL
keyword with a number and a time unit, one of:
HOURS
DAYS
WEEKS
MONTHS
YEARS
Refer to the section on TTL in Concepts for detailed information on the behavior of this feature.
The time-to-live (TTL) for the materialized view can differ from the base table, depending on your needs.
Examples
CREATE MATERIALIZED VIEW trades_hourly_prices AS (
SELECT
timestamp,
symbol,
avg(price) AS avg_price
FROM trades
SAMPLE BY 1h
) PARTITION BY DAY TTL 7 DAYS;
IF NOT EXISTS
An optional IF NOT EXISTS
clause may be added directly after the
CREATE MATERIALIZED VIEW
keywords to indicate that a new view should be
created only if a view with the desired view name does not already exist.
CREATE MATERIALIZED VIEW IF NOT EXISTS trades_weekly_prices AS (
SELECT
timestamp,
symbol,
avg(price) AS avg_price
FROM trades
SAMPLE BY 7d
) PARTITION BY YEAR;
Materialized view names
Materialized view names follow the same rules as regular tables.
OWNED BY (Enterprise)
When a user creates a new materialized view, they are automatically assigned all
materialized view level permissions with the GRANT
option for that view. This
behaviour can can be overridden using OWNED BY
.
If the OWNED BY
clause is used, the permissions instead go to the user, group,
or service account named in that clause.
The OWNED BY
clause cannot be omitted if the materialized view is created by
an external user, as permissions cannot be granted to them.
CREATE GROUP analysts;
CREATE MATERIALIZED VIEW trades_hourly_prices AS (
SELECT
timestamp,
symbol,
avg(price) AS avg_price
FROM trades
SAMPLE BY 1h
) PARTITION BY DAY
OWNED BY analysts;
Query constraints
There is a list of requirements for the queries that are used in materialized views. Refer to this documentation section to learn them.