← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Materialized Views

performance PHP 5.0+ Advanced

Also Known As

materialised views precomputed views cached query result

TL;DR

Pre-computed query results stored as a real table — dramatically faster reads for expensive aggregations at the cost of periodic refresh overhead.

Explanation

A materialized view stores the result of a complex query (heavy aggregations, multi-table joins) as a physical table that can be indexed and queried instantly. Unlike regular views which recompute on every access, materialized views are refreshed on a schedule or on-demand. PostgreSQL supports REFRESH MATERIALIZED VIEW CONCURRENTLY (non-blocking). MySQL lacks native materialized views — they are emulated as real tables populated by event schedulers or application code. Ideal for dashboards and reporting that aggregate millions of rows but can tolerate slightly stale data (last-refreshed 5 minutes ago).

Common Misconception

Materialized views are always up to date like regular views. Regular views execute the query on each access. Materialized views store the result physically and must be explicitly refreshed — they trade freshness for read performance, making them suitable for reports, not real-time data.

Why It Matters

Materialized views pre-compute and store expensive query results — complex aggregations that take seconds to run become instant reads, at the cost of data that may be slightly stale.

Common Mistakes

  • Not refreshing materialized views — stale data silently serves outdated results.
  • Refreshing too frequently — REFRESH MATERIALIZED VIEW locks the view briefly; concurrent refresh avoids this.
  • Using materialized views for frequently changing data where staleness is unacceptable.
  • Not indexing materialized views — they are stored like tables and need indexes for fast access.

Code Examples

✗ Vulnerable
-- Slow query run on every dashboard load:
SELECT category, COUNT(*), SUM(revenue) FROM orders
JOIN products ON orders.product_id = products.id
GROUP BY category; -- 3 seconds on 10M rows

-- Materialized view — pre-computed, instant:
CREATE MATERIALIZED VIEW order_stats AS (above query);
REFRESH MATERIALIZED VIEW CONCURRENTLY order_stats; -- Run via cron
✓ Fixed
-- PostgreSQL: pre-compute expensive aggregate
CREATE MATERIALIZED VIEW monthly_revenue AS
    SELECT
        DATE_TRUNC('month', created_at) AS month,
        SUM(total) AS revenue,
        COUNT(*) AS order_count
    FROM orders
    WHERE status = 'paid'
    GROUP BY 1;

CREATE INDEX ON monthly_revenue(month);

-- Query is now instant (reads pre-computed data)
SELECT * FROM monthly_revenue WHERE month >= '2024-01-01';

-- Refresh (schedule in cron or trigger)
REFRESH MATERIALIZED VIEW CONCURRENTLY monthly_revenue;
-- CONCURRENTLY allows reads during refresh (PostgreSQL 9.4+)

Added 15 Mar 2026
Edited 22 Mar 2026
Views 15
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Perplexity 5 Unknown AI 2 Majestic 1 Google 1 Ahrefs 1
crawler 10
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Create a materialised view for any reporting query taking >1 second — schedule REFRESH MATERIALIZED VIEW CONCURRENTLY during off-peak hours to serve dashboards instantly from pre-computed data
📦 Applies To
PHP 5.0+ web cli
🔗 Prerequisites
🔍 Detection Hints
Dashboard recalculating complex aggregation on every request; report query joining 5+ tables; same GROUP BY with COUNT SUM repeated everywhere
Auto-detectable: ✗ No pganalyze mysql-slow-query-log blackfire
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: File

✓ schema.org compliant