Skip to content

Commit 8db68e8

Browse files
puzpuzpuzgoodrootnwoolmer
authored
Document period materialized views (#202)
Co-authored-by: goodroot <9484709+goodroot@users.noreply.github.com> Co-authored-by: Nick Woolmer <29717167+nwoolmer@users.noreply.github.com>
1 parent d80cce3 commit 8db68e8

File tree

10 files changed

+513
-233
lines changed

10 files changed

+513
-233
lines changed

documentation/guides/mat-views.md

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ As data grows in size, the performance of certain queries can degrade.
5555
Materialized views store the result of a `SAMPLE BY` or time-based `GROUP BY`
5656
query on disk, and keep it automatically up to date.
5757

58-
The refresh of a materialized view is `INCREMENTAL` and very efficient, and
59-
using materialized views can offer 100x or higher query speedups. If you require
60-
the lowest latency queries, for example, for charts and dashboards, use
61-
materialized views!
58+
The refresh of a materialized view is incremental and very efficient, and using
59+
materialized views can offer 100x or higher query speedups. If you require the
60+
lowest latency queries, for example, for charts and dashboards, use materialized
61+
views!
6262

6363
For a better understanding of what materialized views are for, read the
6464
[introduction to materialized views](/docs/concept/mat-views/) documentation.
@@ -106,7 +106,7 @@ If you are unfamiliar with the OHLC concept, please see our
106106

107107
```questdb-sql title="trades_OHLC_15m DDL"
108108
CREATE MATERIALIZED VIEW 'trades_OHLC_15m'
109-
WITH BASE 'trades' REFRESH INCREMENTAL AS
109+
WITH BASE 'trades' REFRESH IMMEDIATE AS
110110
SELECT
111111
timestamp, symbol,
112112
first(price) AS open,
@@ -124,9 +124,9 @@ In this example:
124124
2. The base table is `trades`
125125
- This is the data source, and will trigger incremental refresh when new data
126126
is written.
127-
3. The refresh strategy is `INCREMENTAL`
128-
- The data is automatically refreshed and incrementally written; efficient,
129-
fast, low maintenance.
127+
3. The refresh strategy is `IMMEDIATE`
128+
- The data is automatically refreshed and incrementally written after a base
129+
table transaction occurs; efficient, fast, low maintenance.
130130
4. The `SAMPLE BY` query contains two key column (`timestamp`, `symbol`) and
131131
five aggregates (`first`, `max`, `min`, `last`, `price`) calculated in `15m`
132132
time buckets.
@@ -172,13 +172,61 @@ will not trigger any sort of refresh.
172172

173173
#### Refresh strategies
174174

175-
Currently, only `INCREMENTAL` refresh is supported. This strategy incrementally
176-
updates the view when new data is inserted into the base table. This means that
177-
only new data is written to the view, so there is minimal write overhead.
175+
The `IMMEDIATE` refresh strategy incrementally updates the view when new data is
176+
inserted into the base table. This means that only new data is written to the
177+
view, so there is minimal write overhead.
178178

179179
Upon creation, or when the view is invalidated, a full refresh will occur, which
180180
rebuilds the view from scratch.
181181

182+
Other than `IMMEDIATE` refresh, QuestDB supports `MANUAL` and timer
183+
(`EVERY <interval>`) strategies for materialized views. Manual strategy means
184+
that to refresh the view, you need to run the
185+
[`REFRESH` SQL](/docs/reference/sql/refresh-mat-view/) explicitly. In case of
186+
timer-based refresh the view is refreshed periodically, at the specified
187+
interval.
188+
189+
The refresh strategy of an existing view can be changed any time with the
190+
[`ALTER SET REFRESH`](/docs/reference/sql/alter-mat-view-set-refresh/) command.
191+
192+
## Period materialized views
193+
194+
In certain use cases, like storing trading day information, the data becomes
195+
available at fixed time intervals. In this case, `PERIOD` variant of
196+
materialized views can be used:
197+
198+
```questdb-sql title="Period materialized view"
199+
CREATE MATERIALIZED VIEW trades_daily_prices
200+
REFRESH PERIOD (LENGTH 1d TIME ZONE 'Europe/London' DELAY 2h) AS
201+
SELECT
202+
timestamp,
203+
symbol,
204+
avg(price) AS avg_price
205+
FROM trades
206+
SAMPLE BY 1d;
207+
```
208+
209+
Refer to the following
210+
[documentation page](/docs/reference/sql/create-mat-view/#period-materialized-views)
211+
to learn more on period materialized views.
212+
213+
## Initial refresh
214+
215+
As soon as a materialized view is created an asynchronous refresh is started. In
216+
situations when this is not desirable, `DEFERRED` keyword can be specified along
217+
with the refresh strategy:
218+
219+
```questdb-sql title="Deferred manual refresh"
220+
CREATE MATERIALIZED VIEW trades_daily_prices
221+
REFRESH MANUAL DEFERRED AS
222+
...
223+
```
224+
225+
The `DEFERRED` keyword can be specified for any refresh strategy. Refer to the
226+
following
227+
[documentation page](/docs/reference/sql/create-mat-view/#initial-refresh) to
228+
learn more on the keyword.
229+
182230
#### SAMPLE BY
183231

184232
Materialized views are populated using `SAMPLE BY` or time-based `GROUP BY`
@@ -357,7 +405,7 @@ useful.
357405
## Limitations
358406

359407
- Not all `SAMPLE BY` syntax is supported, for example, `FILL`.
360-
- `INCREMENTAL` refresh is only triggered by inserts into the `base` table, not
408+
- `IMMEDIATE` refresh is only triggered by inserts into the `base` table, not
361409
join tables.
362410

363411
## LATEST ON materialized views
@@ -555,15 +603,6 @@ partitioning capabilities.
555603

556604
### Refresh mechanism
557605

558-
:::note
559-
560-
Currently, QuestDB only supports **incremental refresh** for materialized views.
561-
562-
Future releases will include additional refresh types, such as time-interval and
563-
manual refreshes.
564-
565-
:::
566-
567606
Unlike regular views, which recompute their results at query time, materialized
568607
views in QuestDB are incrementally refreshed as new data is added to the base
569608
table. This approach ensures that only the **relevant time slices** of the view

documentation/reference/function/meta.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,8 @@ materialized_views();
518518

519519
| view_name | refresh_type | base_table_name | last_refresh_start_timestamp | last_refresh_finish_timestamp | view_sql | view_table_dir_name | invalidation_reason | view_status | refresh_base_table_txn | base_table_txn | refresh_limit_value | refresh_limit_unit | timer_start | timer_interval_value | timer_interval_unit |
520520
|------------------|--------------|-----------------|------------------------------|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------|---------------------|-------------|------------------------|----------------|---------------------|--------------------|-------------|----------------------|---------------------|
521-
| trades_OHLC_15m | incremental | trades | 2025-05-30T16:40:37.562421Z | 2025-05-30T16:40:37.568800Z | SELECT timestamp, symbol, first(price) AS open, max(price) as high, min(price) as low, last(price) AS close, sum(amount) AS volume FROM trades SAMPLE BY 15m | trades_OHLC_15m~27 | null | valid | 55141609 | 55141609 | 0 | null | null | 0 | null |
522-
| trades_latest_1d | incremental | trades | 2025-05-30T16:40:37.554274Z | 2025-05-30T16:40:37.562049Z | SELECT timestamp, symbol, side, last(price) AS price, last(amount) AS amount, last(timestamp) as latest FROM trades SAMPLE BY 1d | trades_latest_1d~28 | null | valid | 55141609 | 55141609 | 0 | null | null | 0 | null |
521+
| trades_OHLC_15m | immediate | trades | 2025-05-30T16:40:37.562421Z | 2025-05-30T16:40:37.568800Z | SELECT timestamp, symbol, first(price) AS open, max(price) as high, min(price) as low, last(price) AS close, sum(amount) AS volume FROM trades SAMPLE BY 15m | trades_OHLC_15m~27 | null | valid | 55141609 | 55141609 | 0 | null | null | 0 | null |
522+
| trades_latest_1d | immediate | trades | 2025-05-30T16:40:37.554274Z | 2025-05-30T16:40:37.562049Z | SELECT timestamp, symbol, side, last(price) AS price, last(amount) AS amount, last(timestamp) as latest FROM trades SAMPLE BY 1d | trades_latest_1d~28 | null | valid | 55141609 | 55141609 | 0 | null | null | 0 | null |
523523

524524

525525
## version/pg_catalog.version

documentation/reference/sql/alter-mat-view-set-refresh-start.md

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
title: ALTER MATERIALIZED VIEW SET REFRESH
3+
sidebar_label: SET REFRESH
4+
description:
5+
ALTER MATERIALIZED VIEW SET REFRESH SQL keyword reference documentation.
6+
---
7+
8+
Changes a materialized view's refresh strategy and parameters.
9+
10+
## Syntax
11+
12+
![Flow chart showing the syntax of ALTER MATERIALIZED VIEW SET REFRESH command](/images/docs/diagrams/alterMatViewSetRefresh.svg)
13+
14+
## Description
15+
16+
Sometimes, the view's refresh strategy and its parameters may need to be changed.
17+
Say, you may want to change the view to be timer refreshed instead of immediate
18+
refresh.
19+
20+
The `REFRESH` follows the same format as [CREATE MATERIALIZED VIEW](/docs/reference/sql/create-mat-view/).
21+
22+
## Examples
23+
24+
```questdb-sql
25+
ALTER MATERIALIZED VIEW trades_hourly_prices SET REFRESH EVERY '1h';
26+
```
27+
28+
```questdb-sql
29+
ALTER MATERIALIZED VIEW trades_hourly_prices SET REFRESH PERIOD (LENGTH 1d DELAY 1h);
30+
```
31+
32+
```questdb-sql
33+
ALTER MATERIALIZED VIEW trades_hourly_prices SET REFRESH IMMEDIATE;
34+
```
35+
36+
```questdb-sql
37+
ALTER MATERIALIZED VIEW trades_hourly_prices SET REFRESH MANUAL;
38+
```

0 commit comments

Comments
 (0)