SQL: a view is a stored query, a materialized view is stored rows

A plain view runs every time you select from it. A materialized view holds a snapshot on disk, which is fast to read and stale until you refresh it.

Code
CREATE VIEW paid_orders AS
  SELECT * FROM orders WHERE status = 'PAID';        -- re-runs each time

CREATE MATERIALIZED VIEW daily_revenue AS
  SELECT created_at::date AS d, SUM(total) AS revenue
    FROM orders GROUP BY 1;                          -- stored

REFRESH MATERIALIZED VIEW daily_revenue;

-- CONCURRENTLY avoids locking readers, and needs a unique index:
CREATE UNIQUE INDEX ON daily_revenue (d);
REFRESH MATERIALIZED VIEW CONCURRENTLY daily_revenue;
Output
SELECT * FROM daily_revenue;
  plain view        -> 1,840 ms (full aggregate every time)
  materialized      ->     2 ms (index scan on stored rows)

-- A plain REFRESH takes an exclusive lock for its whole duration.
-- CONCURRENTLY is slower but keeps the view readable throughout.
Advertisement

Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.

Published 2026-08-25