documentation/query/sql/refresh-mat-view.md
Manually triggers a refresh of a materialized view. Use this to restore invalid views, force an immediate update, or refresh a specific time range.
REFRESH MATERIALIZED VIEW viewName [ FULL | INCREMENTAL | RANGE FROM timestamp TO timestamp ]
| Parameter | Description |
|---|---|
viewName | Name of the materialized view to refresh |
FULL | Delete all data and rebuild from scratch |
INCREMENTAL | Process only new data since last refresh |
RANGE FROM ... TO | Refresh only the specified time range |
Deletes all data in the materialized view and rebuilds it from the base table:
REFRESH MATERIALIZED VIEW trades_hourly FULL;
What happens:
valid (reactivates incremental refresh)When to use:
TRUNCATE/UPDATE on base table:::warning Full refresh on large base tables can take significant time. The view remains queryable during refresh but returns stale data until complete. :::
Schedules an incremental refresh that processes only new data:
REFRESH MATERIALIZED VIEW trades_hourly INCREMENTAL;
What happens:
When to use:
MANUAL refresh strategy to control exactly when updates happen:::note
Only works on valid views. If the view is invalid, use FULL instead.
:::
Refreshes only data within a specific time range:
REFRESH MATERIALIZED VIEW trades_hourly
RANGE FROM '2025-05-01T00:00:00Z' TO '2025-05-02T00:00:00Z';
What happens:
When to use:
REFRESH LIMIT):::note Range refresh does not update the incremental refresh checkpoint. Future incremental refreshes continue from where they left off, independent of range refreshes. :::
-- Check why the view is invalid
SELECT view_name, view_status, invalidation_reason
FROM materialized_views()
WHERE view_name = 'trades_hourly';
-- Rebuild the view
REFRESH MATERIALIZED VIEW trades_hourly FULL;
-- Verify it's valid again
SELECT view_name, view_status
FROM materialized_views()
WHERE view_name = 'trades_hourly';
For views with REFRESH MANUAL strategy:
-- Create a manually-refreshed view
CREATE MATERIALIZED VIEW daily_summary
REFRESH MANUAL AS
SELECT timestamp, symbol, sum(amount) AS volume
FROM trades
SAMPLE BY 1d;
-- Refresh when ready (e.g., after batch load completes)
REFRESH MATERIALIZED VIEW daily_summary INCREMENTAL;
When data arrives after the refresh limit:
-- Late data arrived for May 1st
-- Incremental refresh won't pick it up if outside the limit
-- Refresh just that day
REFRESH MATERIALIZED VIEW trades_hourly
RANGE FROM '2025-05-01T00:00:00Z' TO '2025-05-02T00:00:00Z';
| Aspect | Description |
|---|---|
| Execution | Asynchronous - command returns immediately |
| View availability | View remains queryable during refresh (returns current data) |
| Concurrency | Only one refresh runs at a time per view |
| Cancellation | Use CANCEL QUERY to stop a long-running refresh |
SELECT
view_name,
view_status,
refresh_base_table_txn,
base_table_txn,
last_refresh_start_timestamp,
last_refresh_finish_timestamp
FROM materialized_views()
WHERE view_name = 'trades_hourly';
When refresh_base_table_txn equals base_table_txn, the view is fully
up-to-date.
Refreshing a materialized view requires the REFRESH MATERIALIZED VIEW
permission on the specific view:
GRANT REFRESH MATERIALIZED VIEW ON trades_hourly TO user1;
The view creator automatically receives this permission with the GRANT option.
| Error | Cause |
|---|---|
materialized view does not exist | View with specified name doesn't exist |
materialized view is invalid | Cannot run INCREMENTAL on invalid view (use FULL) |
invalid timestamp range | FROM timestamp is after TO timestamp |
permission denied | Missing REFRESH MATERIALIZED VIEW permission (Enterprise) |