-- Created on savesnippets.com ยท https://savesnippets.com/MWf8C00iRe9HF7 -- Regular view โ€” query is re-run each time you SELECT from it CREATE VIEW active_customers AS SELECT u.id, u.email, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE u.status = 'active' GROUP BY u.id, u.email; SELECT * FROM active_customers WHERE order_count > 10; -- Materialized view โ€” result is cached on disk (PostgreSQL) CREATE MATERIALIZED VIEW user_stats AS SELECT u.id, u.email, COUNT(o.id) AS order_count, SUM(o.amount) AS lifetime_value, MAX(o.created_at) AS last_order FROM users u LEFT JOIN orders o ON o.user_id = u.id GROUP BY u.id, u.email; -- Index materialized views like a real table CREATE INDEX idx_user_stats_ltv ON user_stats (lifetime_value DESC); -- Refresh โ€” blocks readers REFRESH MATERIALIZED VIEW user_stats; -- ... or refresh without blocking (requires a UNIQUE index on the MV) REFRESH MATERIALIZED VIEW CONCURRENTLY user_stats;