Materialized View

A materialized view is a view whose query result is physically stored on disk, unlike a regular view which re-executes its query every time. This trades storage for read performance — ideal for expensive aggregations, joins, or OLAP queries that don’t need real-time data.

Syntax (PostgreSQL)

CREATE MATERIALIZED VIEW monthly_sales AS
SELECT date_trunc('month', sale_date) AS month,
       product_id,
       SUM(amount) AS total,
       COUNT(*) AS num_orders
FROM sales
GROUP BY 1, 2;

Refreshing

The data becomes stale as the underlying tables change. Refresh manually:

-- Full refresh (blocks reads during refresh)
REFRESH MATERIALIZED VIEW monthly_sales;
 
-- Concurrent refresh (allows reads during refresh, requires UNIQUE index)
REFRESH MATERIALIZED VIEW CONCURRENTLY monthly_sales;

Automate with a cron job, trigger, or application logic depending on staleness tolerance.

Regular View vs Materialized View

AspectRegular ViewMaterialized View
StorageNone (virtual)Physical (on disk)
Query executionEvery accessOnly on refresh
Read speedSame as underlying queryFast (pre-computed)
Data freshnessAlways currentStale between refreshes
Index supportNo (indexes on base tables)Yes (can create indexes on the MV)
Write-throughSome views are updatableNot updatable

Use Cases

  • Dashboard aggregations — Pre-compute daily/weekly/monthly summaries
  • Expensive joins — Cache the result of multi-table joins
  • Data Warehousing — Summary tables for OLAP queries
  • Search acceleration — Pre-join and denormalize for Full Text Search or filtering

Availability

DBMSSupport
PostgreSQLFull support with CONCURRENTLY option
OracleFull support with automatic refresh options
SQL ServerCalled “Indexed Views”
MySQLNot natively supported (simulate with table + trigger)
SQLiteNot supported