Home Database Materialized Views & Clustering: Performance Guide
Intermediate 3 min · July 17, 2026
Materialized Views, Clustering, and Automatic Table Maintenance

Materialized Views & Clustering: Performance Guide

Master Snowflake materialized views, automatic clustering, and table maintenance.

N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Lessons pulled from things that broke in production.

Follow
Production
production tested
July 17, 2026
last updated
2,439
articles · all by Naren
Before you start⏱ 15-20 min read
  • Basic understanding of SQL SELECT, GROUP BY, and aggregations.
  • Familiarity with Snowflake environment and basic table operations.
  • Knowledge of indexing concepts (helpful but not required).
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Materialized views pre-compute query results and auto-refresh, speeding up complex aggregations.
  • Automatic clustering reorganizes data based on clustering keys to improve query performance.
  • Use materialized views for expensive aggregations on large tables; clustering benefits range-filtered queries.
  • Maintenance is automatic but requires careful key selection and monitoring.
  • Combine both for maximum performance on large, frequently queried datasets.
✦ Definition~90s read
What is Materialized Views, Clustering, and Automatic Table Maintenance?

Snowflake materialized views and automatic clustering are features that pre-compute query results and reorganize data on disk to dramatically improve query performance for large datasets.

Think of a materialized view like a pre-made summary report that updates itself whenever new data comes in.
Plain-English First

Think of a materialized view like a pre-made summary report that updates itself whenever new data comes in. Instead of recalculating totals every time you ask, you just read the summary. Clustering is like organizing a filing cabinet so that related documents are stored together, making it faster to find what you need.

In Snowflake, as your data grows, queries that scan entire tables can become painfully slow. Two powerful features—materialized views and automatic clustering—help you keep performance high without manual tuning. Materialized views store pre-computed results of expensive aggregations, automatically refreshing as base data changes. Automatic clustering reorganizes table data on disk based on one or more clustering keys, reducing the amount of data scanned for range-filtered queries. Together, they form a robust foundation for self-optimizing data warehouses. This tutorial will guide you through creating, managing, and debugging these features with production-ready examples. You'll learn when to use each, how to monitor their effectiveness, and how to avoid common pitfalls that can degrade performance or increase costs.

What Are Materialized Views in Snowflake?

Materialized views in Snowflake are pre-computed result sets that are automatically refreshed when the underlying base table changes. Unlike standard views, which execute the query each time they are accessed, materialized views store the actual data, dramatically reducing query latency for complex aggregations. They are ideal for dashboards, reporting, and any scenario where the same expensive query runs repeatedly. Snowflake handles the refresh automatically, but you can control the refresh interval or trigger it manually. Materialized views incur storage costs and compute costs for refresh, so they are best used for queries that run frequently and are expensive to compute from scratch.

create_materialized_view.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- Create a materialized view for daily sales by product
CREATE MATERIALIZED VIEW daily_sales_mv AS
SELECT 
    sale_date,
    product_id,
    SUM(quantity) AS total_quantity,
    SUM(amount) AS total_amount
FROM sales
GROUP BY sale_date, product_id;

-- Query the materialized view
SELECT * FROM daily_sales_mv
WHERE sale_date = '2024-01-15'
ORDER BY total_amount DESC;
Output
sale_date | product_id | total_quantity | total_amount
2024-01-15 | 102 | 150 | 4500.00
2024-01-15 | 105 | 120 | 3600.00
...
🔥Materialized View Limitations
📊 Production Insight
Always verify that your query matches the materialized view definition exactly. Even a missing column or different filter can cause Snowflake to ignore the view and scan the base table.
🎯 Key Takeaway
Materialized views store pre-computed results and auto-refresh, ideal for repeated expensive aggregations.

Creating and Managing Materialized Views

To create a materialized view, use the CREATE MATERIALIZED VIEW statement followed by a SELECT query. The query must be deterministic and cannot include non-deterministic functions like CURRENT_TIMESTAMP. You can also specify a clustering key on the materialized view itself to further optimize queries against it. Managing materialized views includes checking their refresh status, altering refresh intervals, and dropping them when no longer needed. Use SHOW MATERIALIZED VIEWS to list all views and their properties. The refresh is automatic but you can force a refresh with ALTER MATERIALIZED VIEW ... REFRESH.

manage_materialized_view.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
-- List all materialized views
SHOW MATERIALIZED VIEWS IN DATABASE mydb;

-- Check refresh history
SELECT * FROM INFORMATION_SCHEMA.MATERIALIZED_VIEW_REFRESH_HISTORY
WHERE VIEW_NAME = 'DAILY_SALES_MV'
ORDER BY REFRESH_START_TIME DESC;

-- Force a refresh
ALTER MATERIALIZED VIEW daily_sales_mv REFRESH;

-- Drop a materialized view
DROP MATERIALIZED VIEW daily_sales_mv;
Output
name | database | schema | refresh_mode | cluster_by
DAILY_SALES_MV | MYDB | PUBLIC | AUTO | (SALE_DATE)
REFRESH_START_TIME | REFRESH_END_TIME | BYTES_WRITTEN
2024-01-15 02:00:00.000 | 2024-01-15 02:00:05.000 | 1048576
💡Refresh Costs
📊 Production Insight
If you have a materialized view that is not being refreshed automatically, check if the base table has any clustering key. Snowflake recommends clustering the base table for efficient incremental refresh.
🎯 Key Takeaway
Use SHOW and INFORMATION_SCHEMA to monitor materialized views; force refresh when needed.

Automatic Clustering in Snowflake

Automatic clustering reorganizes the micro-partitions of a table based on one or more clustering keys. This reduces the amount of data scanned for queries that filter on those keys. Snowflake automatically reclusters data as new data is inserted, updated, or deleted. You define clustering keys using the CLUSTER BY clause when creating or altering a table. The system then maintains the clustering order over time. Clustering is especially beneficial for large tables (hundreds of gigabytes or more) and for queries with range predicates (e.g., WHERE date BETWEEN ...).

clustering_example.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- Create a table with a clustering key on sale_date
CREATE TABLE sales (
    sale_id INTEGER,
    sale_date DATE,
    product_id INTEGER,
    quantity INTEGER,
    amount DECIMAL(10,2)
) CLUSTER BY (sale_date);

-- Alternatively, add clustering key to existing table
ALTER TABLE sales CLUSTER BY (sale_date, product_id);

-- Check clustering depth
SELECT SYSTEM$CLUSTERING_DEPTH('sales');

-- View clustering information
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'SALES';
Output
SYSTEM$CLUSTERING_DEPTH('sales')
2.5
TABLE_CATALOG | TABLE_NAME | CLUSTERING_KEY | CLUSTERING_DEPTH
MYDB | SALES | (SALE_DATE) | 2.5
⚠ Clustering Key Selection
📊 Production Insight
Clustering depth is a measure of how well-clustered your table is. A depth close to 1 indicates excellent clustering. Monitor it regularly; if it increases, consider manual reclustering or adjusting keys.
🎯 Key Takeaway
Automatic clustering reorganizes data based on keys to improve range query performance.

Combining Materialized Views and Clustering

For maximum performance, combine materialized views with clustering. Cluster the base table on the columns used in the materialized view's GROUP BY or WHERE clauses. This speeds up both the materialized view refresh and any queries that scan the base table. Additionally, you can cluster the materialized view itself if you frequently query it with filters. However, note that materialized views inherit clustering from the base table by default, but you can override it.

combine_mv_clustering.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- Base table with clustering
CREATE TABLE sales (
    sale_id INTEGER,
    sale_date DATE,
    product_id INTEGER,
    quantity INTEGER,
    amount DECIMAL(10,2)
) CLUSTER BY (sale_date);

-- Materialized view with its own clustering
CREATE MATERIALIZED VIEW daily_sales_mv
CLUSTER BY (sale_date)
AS
SELECT sale_date, product_id, SUM(quantity) AS total_qty, SUM(amount) AS total_amt
FROM sales
GROUP BY sale_date, product_id;

-- Query that benefits from both
SELECT * FROM daily_sales_mv
WHERE sale_date BETWEEN '2024-01-01' AND '2024-01-31'
ORDER BY total_amt DESC;
Output
sale_date | product_id | total_qty | total_amt
2024-01-15 | 102 | 150 | 4500.00
2024-01-20 | 105 | 130 | 3900.00
...
💡Clustering Materialized Views
📊 Production Insight
When you create a materialized view on a clustered base table, Snowflake automatically uses the base table's clustering for the view's storage. However, if your queries on the view use different filters, consider adding a separate clustering key on the view.
🎯 Key Takeaway
Cluster base tables on columns used in materialized views to improve refresh and query performance.

Monitoring and Maintaining Performance

Snowflake provides several tools to monitor the performance of materialized views and clustering. Use the ACCOUNT_USAGE schema and INFORMATION_SCHEMA to track refresh history, clustering depth, and credit consumption. The QUERY_HISTORY view can show whether queries are using materialized views. For clustering, you can manually recluster a table using ALTER TABLE ... RECLUSTER if automatic clustering is not keeping up. Regular monitoring helps you identify when to adjust clustering keys or drop unused materialized views.

monitor_performance.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
-- Check if a query used a materialized view
SELECT query_id, query_text, materialized_view_name
FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY(
    DATEADD('day', -1, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP))
WHERE query_text LIKE '%daily_sales_mv%';

-- View clustering history
SELECT * FROM TABLE(INFORMATION_SCHEMA.AUTOMATIC_CLUSTERING_HISTORY(
    DATEADD('day', -7, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP))
WHERE TABLE_NAME = 'SALES';

-- Manual recluster if needed
ALTER TABLE sales RECLUSTER;
Output
query_id | query_text | materialized_view_name
0192837465 | SELECT * FROM daily_sales_mv WHERE ... | DAILY_SALES_MV
TABLE_NAME | CLUSTERING_DEPTH_START | CLUSTERING_DEPTH_END | CREDITS_USED
SALES | 3.2 | 1.8 | 0.5
🔥Cost Management
📊 Production Insight
If you notice that automatic clustering is not keeping your table well-clustered (depth > 3), you may need to manually recluster or adjust your clustering keys. Also, consider the frequency of DML operations; heavy inserts can degrade clustering quickly.
🎯 Key Takeaway
Regularly monitor query history, clustering depth, and refresh costs to maintain optimal performance.

Best Practices and Common Pitfalls

When using materialized views and clustering, follow these best practices: 1) Match materialized view definitions exactly to your most common query patterns. 2) Use clustering keys on columns that appear in WHERE clauses with range predicates. 3) Avoid clustering on high-cardinality columns like primary keys. 4) Monitor clustering depth and refresh history regularly. 5) Test with EXPLAIN to ensure materialized views are being used. Common pitfalls include creating materialized views with complex joins (not allowed), using too many clustering keys, and neglecting to drop unused materialized views, which incur storage costs.

best_practices.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- Good: clustering on date column used in range queries
CREATE TABLE orders CLUSTER BY (order_date) AS SELECT * FROM raw_orders;

-- Bad: clustering on high-cardinality column like order_id
-- (won't group data well)

-- Good: materialized view matching common query
CREATE MATERIALIZED VIEW monthly_sales AS
SELECT DATE_TRUNC('month', sale_date) AS month, SUM(amount) AS total
FROM sales GROUP BY month;

-- Check if view is used
EXPLAIN SELECT DATE_TRUNC('month', sale_date) AS month, SUM(amount) AS total
FROM sales WHERE sale_date >= '2024-01-01' GROUP BY month;
Output
Operation | Object
GlobalStats |
TableScan | SALES
PartitionsScanned: 10/100
MaterializedViewUsed: MONTHLY_SALES
⚠ Avoid Over-Clustering
📊 Production Insight
A common mistake is creating a materialized view that is never used because the query has a slight difference (e.g., different column alias). Always use EXPLAIN to verify.
🎯 Key Takeaway
Match materialized views to queries, choose clustering keys wisely, and monitor regularly.
● Production incidentPOST-MORTEMseverity: high

The Midnight Query Meltdown

Symptom
The daily sales aggregation query timed out after 60 minutes, blocking downstream reports.
Assumption
The developer assumed the query was slow due to increased data volume and added more warehouse resources.
Root cause
The base table had no clustering key, and data was inserted in random order. Over time, micro-partitions became fragmented, causing full table scans. A materialized view that should have helped was not being used because the query didn't match its definition exactly.
Fix
Created a materialized view on the exact query pattern (daily sales by product), added a clustering key on the date column, and enabled automatic clustering. The query then ran in under 10 seconds.
Key lesson
  • Always match materialized view definitions to your most common query patterns.
  • Use clustering keys on columns used in WHERE clauses with range filters.
  • Monitor clustering depth and materialized view freshness regularly.
  • Test materialized views with EXPLAIN to ensure they are being used.
  • Don't rely solely on scaling warehouses; optimize data layout first.
Production debug guideSymptom to Action4 entries
Symptom · 01
Query is slow despite a materialized view existing
Fix
Check if the query matches the materialized view definition exactly (same columns, filters, grouping). Use EXPLAIN to see if the view is used.
Symptom · 02
Materialized view refresh takes too long
Fix
Check the base table for frequent DML operations. Consider increasing warehouse size for the refresh or reviewing the view definition.
Symptom · 03
Clustering is not improving query performance
Fix
Verify clustering keys are on columns used in WHERE clauses with range predicates. Check clustering depth in INFORMATION_SCHEMA.TABLES.
Symptom · 04
Automatic clustering costs are high
Fix
Review clustering key choice; too many keys or high cardinality keys can increase re-clustering costs. Consider manual clustering for stable datasets.
★ Quick Debug Cheat SheetCommon symptoms and immediate actions for materialized views and clustering issues.
Materialized view not used
Immediate action
Check query matches view definition
Commands
EXPLAIN SELECT ...
SHOW MATERIALIZED VIEWS LIKE '%view_name%'
Fix now
Rewrite query to match view exactly or drop and recreate view with correct definition.
High clustering costs+
Immediate action
Review clustering key cardinality
Commands
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='...'
SELECT SYSTEM$CLUSTERING_DEPTH('...')
Fix now
Simplify clustering key to fewer columns or lower cardinality columns.
Slow refresh+
Immediate action
Check base table DML frequency
Commands
SELECT * FROM INFORMATION_SCHEMA.MATERIALIZED_VIEW_REFRESH_HISTORY WHERE VIEW_NAME='...'
SHOW TABLES LIKE '%base_table%'
Fix now
Reduce DML frequency or increase refresh warehouse size.
FeatureMaterialized ViewsAutomatic Clustering
PurposePre-compute query resultsReorganize data on disk
Performance BenefitReduces query execution time for matching queriesReduces data scanned for range-filtered queries
MaintenanceAutomatic refresh on base table changesAutomatic re-clustering based on DML
CostStorage + refresh compute creditsCompute credits for re-clustering
When to UseExpensive aggregations run frequentlyLarge tables with range-filtered queries
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
create_materialized_view.sqlCREATE MATERIALIZED VIEW daily_sales_mv ASWhat Are Materialized Views in Snowflake?
manage_materialized_view.sqlSHOW MATERIALIZED VIEWS IN DATABASE mydb;Creating and Managing Materialized Views
clustering_example.sqlCREATE TABLE sales (Automatic Clustering in Snowflake
combine_mv_clustering.sqlCREATE TABLE sales (Combining Materialized Views and Clustering
monitor_performance.sqlSELECT query_id, query_text, materialized_view_nameMonitoring and Maintaining Performance
best_practices.sqlCREATE TABLE orders CLUSTER BY (order_date) AS SELECT * FROM raw_orders;Best Practices and Common Pitfalls

Key takeaways

1
Materialized views pre-compute and auto-refresh results for repeated expensive queries, reducing query latency.
2
Automatic clustering reorganizes data based on keys to improve range-filtered query performance.
3
Combine both features by clustering base tables on columns used in materialized views.
4
Monitor clustering depth and materialized view usage regularly to maintain performance and control costs.
5
Use EXPLAIN to verify materialized view usage and adjust definitions as needed.

Common mistakes to avoid

4 patterns
×

Creating a materialized view that doesn't match any query pattern

×

Clustering on a high-cardinality column like a primary key

×

Neglecting to monitor clustering depth

×

Assuming materialized views are automatically used

INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is a materialized view and how does it differ from a standard view?
Q02SENIOR
How do you choose a clustering key for a Snowflake table?
Q03SENIOR
Explain how to verify that a materialized view is being used by a query.
Q04SENIOR
What are the limitations of materialized views in Snowflake?
Q05SENIOR
How would you troubleshoot a slow materialized view refresh?
Q01 of 05JUNIOR

What is a materialized view and how does it differ from a standard view?

ANSWER
A materialized view stores pre-computed results and auto-refreshes, while a standard view executes the query each time it's accessed. Materialized views improve performance for repeated expensive queries but incur storage and refresh costs.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
Can materialized views be used with joins?
02
How often do materialized views refresh automatically?
03
What is clustering depth and why does it matter?
04
Can I cluster a materialized view?
05
Does automatic clustering work on all tables?
N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Lessons pulled from things that broke in production.

Follow
Verified
production tested
July 17, 2026
last updated
2,439
articles · all by Naren
🔥

That's Snowflake. Mark it forged?

3 min read · try the examples if you haven't

Previous
Stored Procedures, UDFs, and Snowflake Scripting
16 / 33 · Snowflake
Next
Dynamic Tables: Declarative Data Pipelines