Skip to content

Materialized Views

Materialized Views

Pre-compute and cache query results for faster access with automatic or incremental refresh.

Creating Materialized Views

CREATE MATERIALIZED VIEW monthly_sales AS
SELECT
DATE_TRUNC('month', created_at) as month,
COUNT(*) as order_count,
SUM(total) as revenue
FROM orders
GROUP BY DATE_TRUNC('month', created_at);

With Options

CREATE MATERIALIZED VIEW active_users AS
SELECT id, name, last_login FROM users WHERE active = true
WITH (
auto_refresh = true,
max_cpu_percent = 25,
staleness_threshold = 3600
);

Refresh Strategies

Manual Refresh

REFRESH MATERIALIZED VIEW monthly_sales;

Concurrent Refresh (Non-blocking)

REFRESH MATERIALIZED VIEW CONCURRENTLY monthly_sales;

Incremental Refresh

REFRESH MATERIALIZED VIEW monthly_sales INCREMENTALLY;

Configuration Options

OptionTypeDescription
auto_refreshbooleanEnable automatic refresh
staleness_thresholdintegerSeconds before view is considered stale
max_cpu_percentintegerCPU limit for refresh operations
priorityintegerRefresh priority (0=low, 3=critical)
refresh_strategystring’manual’, ‘auto’, ‘incremental’

Alter Options After Creation

ALTER MATERIALIZED VIEW monthly_sales SET (
staleness_threshold = 1800,
max_cpu_percent = 15,
priority = 2
);

Monitoring

Check Staleness

SELECT * FROM pg_mv_staleness();

REPL Commands

Terminal window
\dmv # List materialized views
\dmv view_name # Describe specific view

Dropping Views

DROP MATERIALIZED VIEW IF EXISTS monthly_sales;

Best Practices

  1. Use incremental refresh for large views with small changes
  2. Set appropriate staleness thresholds for your use case
  3. Schedule heavy refreshes during low-traffic periods
  4. Monitor CPU usage with max_cpu_percent