When many dashboards ask the same coarse questions, compute the answer once. A pre-aggregate (rollup) stores the facts summed to a coarser grain; queries at that grain or above read it instead of the facts:
DROP MATERIALIZED VIEW IF EXISTS mart.mv_region_group_month;
CREATE MATERIALIZED VIEW mart.mv_region_group_month AS
SELECT date_trunc('month', d.full_date)::date AS month, c.region, b.genre_group,
p.status, sum(f.gross_amount) AS gross, sum(f.qty) AS copies, count(*) AS lines
FROM mart.fact_sales f JOIN mart.dim_date d USING (date_key)
JOIN mart.dim_customer c USING (customer_key) JOIN mart.dim_book b USING (book_key)
JOIN mart.dim_order_profile p USING (profile_key)
GROUP BY 1, 2, 3, 4;
SELECT count(*) AS mv_rows FROM mart.mv_region_group_month;
\timing on
SELECT c.region, sum(f.gross_amount) FROM mart.fact_sales f -- from the facts
JOIN mart.dim_date d USING (date_key) JOIN mart.dim_customer c USING (customer_key)
JOIN mart.dim_order_profile p USING (profile_key)
WHERE d.year = 2026 AND p.status <> 'cancelled' GROUP BY 1 ORDER BY 1;
SELECT region, sum(gross) FROM mart.mv_region_group_month -- from the rollup
WHERE month >= '2026-01-01' AND status <> 'cancelled' GROUP BY 1 ORDER BY 1;Americas | 526089.22 ... Time: 55.583 ms Americas | 526089.22 ... Time: 0.552 ms
The 508-row rollup gave the same 2026 regional totals 10 to 100 times faster (two runs) than four joins over 137,944 facts. The price is freshness and coverage: refresh it after each load (Concurrent Refresh), and it cannot answer below its grain. Store additive measures (Measure Additivity) so it can be summed further; ClickHouse 29,491 maintains such rollups incrementally (Incremental Materialized Views).
A result cache stores the answer to an exact query. Snowflake keeps persisted results for 24 hours (extended on reuse up to 31 days) while the data is unchanged; BigQuery 1 caches results for about 24 hours, charges nothing for a hit, and never caches queries using CURRENT_TIMESTAMP() and similar functions. PostgreSQL 1,289 has no result cache, so a BI tool's cache or a rollup does the job.