skip to content

When is a Snowflake materialized view worth its maintenance cost, and what can it not contain?

level: seniorimportance: should knowfreq 44%

answer

  1. it only ever watches one table
  2. the optimizer may use it without being asked
  3. the bill scales with how much the base table changes
  4. reads never return stale rows
  5. joins push you to a different object entirely

basics

~20 s

A Snowflake materialized view pays off when an expensive projection or aggregate over one slowly-changing table is queried far more often than the base table changes. It cannot join tables, use window functions, or read another view, and Snowflake maintains it with serverless credits proportional to base-table churn.

solid answer

~50 s

Snowflake materialized views are an Enterprise Edition feature that persist the result of a query over a **single** base table. The restrictions are the first half of the answer: no joins, no window functions, no reading another view or materialized view, and only a supported subset of aggregate functions. The second half is cost: Snowflake maintains the view automatically through a background **serverless** service, billed in credits roughly in proportion to how much the base table changes — so a high-churn table can make maintenance cost more than the queries you were saving. Results are always consistent: if maintenance is behind, Snowflake combines the view with newer base-table data rather than returning stale rows. The optimizer can also rewrite queries written against the **base table** to use the view. The heuristic: read-heavy, change-light, expensive projection or aggregate over one table. For multi-table transformations, dynamic tables are the modern Snowflake answer.

code

sql · 11 lines
sql
-- Legal: one table, aggregate, no window functions
CREATE MATERIALIZED VIEW mv_daily_sales AS
SELECT DATE_TRUNC('day', order_ts) AS day, country, SUM(amount) AS amount
FROM sales
GROUP BY 1, 2;

-- Illegal in Snowflake: joins another table
-- CREATE MATERIALIZED VIEW mv_bad AS
-- SELECT c.region, SUM(s.amount)
-- FROM sales s JOIN customers c ON c.id = s.customer_id
-- GROUP BY 1;

go deeper

for a junior

Know that a materialized view stores a precomputed result so repeated queries read something small, and that Snowflake keeps it up to date for you rather than requiring a manual refresh.

for a middle

Explain the restrictions — single base table, no joins, no window functions, not over another view — and that background maintenance consumes serverless credits scaled to base-table churn.

for a senior

Show the cost arithmetic: maintenance credits plus storage versus warehouse time saved, measured from usage views, and know when a clustering key on the view or a task-built table is the better answer.

for a principal

Own the decision framework across the alternatives — cacheable query shapes, materialized views, dynamic tables, scheduled aggregates — and the governance that stops teams accumulating views nobody has costed.

## What it is A materialized view stores the precomputed result of a query so that later reads scan a small persisted object instead of re-deriving it. In Snowflake it is a first-class object maintained **automatically** — there is no refresh statement you schedule and no staleness you have to reason about at read time. ```sql CREATE MATERIALIZED VIEW mv_daily_sales AS SELECT DATE_TRUNC('day', order_ts) AS day, country, SUM(amount) AS amount FROM sales GROUP BY 1, 2; ``` It is available on Enterprise Edition and above. ## The restrictions The restrictions are narrow enough that they decide most design conversations: - **One base table only.** No joins, no subqueries against other tables, no `UNION`. - **No window functions.** - **Cannot be defined on a view or another materialized view.** - **Only a supported subset of aggregate functions.** The practical reading: a Snowflake materialized view is for *filtering, projecting and aggregating one table*, not for modelling. A denormalized fact-plus-dimension result is out of scope by construction. ## Consistency Snowflake does not hand you stale rows. Maintenance runs in the background, and if the view has not caught up with recent DML, a query against it combines the materialized data with the newer base-table changes to produce a current answer. The cost of that is that reads against a badly lagging view get slower — the saving erodes as churn grows — but correctness is never the thing you trade away. ## Automatic rewrite The optimizer can redirect a query written against the base table to a materialized view that satisfies it. This is what makes materialized views useful for BI traffic you do not control: analysts and tools keep querying the fact table, and eligible queries silently get the cheap path. You do not have to migrate every dashboard's SQL to see the benefit. ## The cost model — the half candidates forget Two costs, both real: 1. **Storage** for the materialized result, billed like any table. 2. **Maintenance credits**, consumed by a serverless background service, roughly proportional to how much the base table changes. There is no warehouse to suspend and no way to make it free while the view exists. That gives a simple decision rule. Let *R* be how often and how expensively the result is read, and *C* be how much the base table churns. Materialize when *R* is large and *C* is small. A table under continuous ingestion with a materialized view over it can quietly become one of the largest lines on the bill — visible in `ACCOUNT_USAGE.MATERIALIZED_VIEW_REFRESH_HISTORY` and in `METERING_DAILY_HISTORY` by service type. Check both before and after creating one. ## Alternatives, and when each wins - **Do nothing.** If the query result is reused by the query result cache — a stable predicate over a table that changes a few times a day — you already get near-zero cost with no maintenance at all. Try this before materializing. - **A scheduled aggregate table** built by a task on a warehouse you control. More work, but the cost is a warehouse you can size, schedule and suspend, and the transformation can join freely. - **Dynamic tables**, Snowflake's declarative pipeline object, which handle multi-table transformations with a declared target lag — the natural answer to "but I need a join". Assumes a current Snowflake release. - **Clustering the base table**, when the problem is that queries scan too much rather than that they recompute too much. ## Operational notes A materialized view can carry its own clustering key, which is often the real win: the base table is ordered for loading, the view is ordered for the dashboard's filter. Materialized views can also be defined over external tables, which is a common way to make a repeatedly-queried external dataset cheap to read. `SHOW MATERIALIZED VIEWS` reports each view's maintenance state, and a view can become invalidated by DDL on the base table — dropping a referenced column, for instance — so schema changes need to account for dependent views. ## The answer an interviewer wants Name the single-table restriction and the serverless maintenance cost in the same breath, then give the read-heavy/change-light heuristic and say what you would try first — result-cache-friendly query shapes, then a materialized view, then a scheduled table or dynamic table when a join is required.

  • The dashboard needs a fact table joined to two dimensions. What do you use instead?
    Not a materialized view — Snowflake's are single-table only. Build the denormalized result with a task-driven table on a warehouse you control, or declare a dynamic table with a target lag so Snowflake maintains the pipeline for you. Both allow joins; the difference is who owns the scheduling and the compute.
  • How do you tell whether an existing materialized view is earning its keep?
    Compare its maintenance credits in MATERIALIZED_VIEW_REFRESH_HISTORY against the warehouse time it saves — estimate the latter from QUERY_HISTORY for the queries it serves, before and after. Add its storage. A view over a high-churn table often costs more in maintenance than the queries it replaced ever cost in compute.
  • Why can a query against the base table get faster after you create a materialized view over it?
    Snowflake's optimizer can rewrite eligible queries written against the base table to read the materialized view instead. That is what makes materialized views useful against BI traffic whose SQL you do not control — nobody has to change a dashboard for the cheaper path to be taken.

saying these in an interview costs you the question

  • Proposes a materialized view over a join in Snowflake
  • Ignores the serverless maintenance credits entirely
  • Thinks reads can return stale materialized data
  • Assumes you must schedule a refresh yourself
  • Reaches for one before checking whether the result cache already helps

context