CREATE MATERIALIZED VIEW stores pre-computed query results in BigQuery, giving sub-second reads while Google handles automatic, incremental refreshes.
Materialized views persist query results on disk, so downstream dashboards read from stored data instead of re-running the base query. You gain faster response times and lower on-demand query costs, at the price of extra storage.
Use CREATE MATERIALIZED VIEW
followed by optional refresh options and the query definition. BigQuery refreshes incrementally whenever base tables change, or on the schedule you set.
The example below pre-computes each customer’s lifetime spend, perfect for customer-profile APIs and embedded analytics.
CREATE MATERIALIZED VIEW IF NOT EXISTS ecommerce.mv_customer_spend
OPTIONS (
enable_refresh = TRUE,
refresh_interval_minutes = 60
) AS
SELECT
c.id AS customer_id,
c.name AS customer_name,
SUM(o.total_amount) AS lifetime_value,
MAX(o.order_date) AS last_order
FROM `ecommerce.Customers` c
JOIN `ecommerce.Orders` o ON o.customer_id = c.id
GROUP BY customer_id, customer_name;
By default, BigQuery performs automatic incremental refreshes every 30 minutes when new data arrives. Override with refresh_interval_minutes
or disable automatic refresh and trigger ALTER MATERIALIZED VIEW ... REFRESH
manually.
Yes. Use deterministic expressions only. Non-deterministic functions such as RAND()
or CURRENT_TIMESTAMP()
are not allowed in a materialized view definition.
Keep materialized views in a mv_*
or derived
dataset to separate them from raw tables. This simplifies permissioning and cost tracking.
Expose INFORMATION_SCHEMA.MATERIALIZED_VIEWS
for ops dashboards or set up Cloud Monitoring alerts on bigquery.googleapis.com/storage_bytes
and query/avg_latency
.
ALTER MATERIALIZED VIEW ecommerce.mv_customer_spend REFRESH;
Use this after backfilling historical data to make the view immediately consistent.
Materialized views cannot include ORDER BY
, LIMIT
, HAVING
, or subqueries in the SELECT list. The query must reference only a single project.
It reduces compute costs for repeated reads but adds storage charges. Calculate ROI by comparing storage bytes to avoided query slots.
Yes, joins are supported as long as the query is deterministic and stays within one project.