# Materialized View

> Materialized views refresh in the background using serverless credits whenever base-table data changes, so a view over a busy table bills even when 0 queries read it. ZopNight discovers them via SHOW MATERIALIZED VIEWS IN ACCOUNT and weighs refresh credits against query hits, flagging views whose maintenance cost outruns their read benefit.

Source: https://zop.dev/integrations/snowflake/materialized-view
Updated: 2026-08-19

---

A materialized view precomputes results so reads come back fast. It pays for that speed with background maintenance that consumes serverless credits every time the base table changes. No warehouse needs to be running when it happens; the refresh meter is Snowflake's own, which makes this one of the easiest charges on the platform to never notice.

## Compute with no warehouse attached

Refresh work draws from a serverless credit stream, separate from any warehouse you own and separate from storage. The consequence is easy to miss: a materialized view bills on write activity, not read activity. Its cost driver is how often the base table changes. Querying the view (or never querying it) changes nothing about that.

## The upside-down view

The failure mode is a view over a hot table that few queries touch. Maintenance runs constantly, reads almost never happen, and the view is a net loss at any query volume near zero. Dropping it is pure savings with no performance cost anyone would feel. The inverse case, a stable base table serving heavy reads, is where materialized views earn their keep.

## Where they sit in inventory

Discovery lists them with `SHOW MATERIALIZED VIEWS IN ACCOUNT`, parents each view to its database with the schema folded into its identifier, and skips anything living in Snowflake-provided shared databases. Every SHOW column lands in the resource's metadata as-is, so a new column Snowflake adds surfaces without a discoverer change.

## The drop decision needs both meters

ZopNight weighs refresh credits against query hits per view and recommends dropping views whose maintenance exceeds their read benefit. Neither number alone settles it: cheap refreshes on a dead view still lose, and expensive refreshes serving a critical dashboard still win.

## Measure refresh spend per view

```sql
SELECT database_name, schema_name, table_name,
       SUM(credits_used) AS refresh_credits_30d
FROM SNOWFLAKE.ACCOUNT_USAGE.MATERIALIZED_VIEW_REFRESH_HISTORY
WHERE start_time > DATEADD('day', -30, CURRENT_TIMESTAMP())
GROUP BY database_name, schema_name, table_name
ORDER BY refresh_credits_30d DESC;
```

Allow for the usual `ACCOUNT_USAGE` latency of up to 3 hours when checking a view you created moments ago.
