What you will be able to do
- Explain the warehouse cache and the persisted query result cache, including when each is lost
- Set auto-suspend to suit a workload's cache needs and idle-credit cost
- Decide when a table needs a clustering key and choose good key columns
- Choose between search optimization, clustering, materialized views and query acceleration, and know which ones add storage or compute cost
1.Cache layers, cache expiration and auto-suspend
The sources describe two cache layers. The first is the warehouse cache, which is a cache of table data held by a running warehouse. Later queries on the same warehouse can read from it instead of reading the tables, and the Query Profile reports this as the percentage of data scanned from the local disk cache. The second is persisted query results. When a query repeats and nothing has changed, Snowflake skips execution and returns the earlier result. That persisted result expires after 24 hours. Each reuse resets the 24-hour period, up to a maximum of 31 days from when the query first ran. (Snowflake's metadata cache isn't covered by the sources for this lesson. Neither is auto-resume beyond its relationship to suspension, so check the official docs for those details.)
Result reuse has conditions. Typically a result is reused only if all of these hold:
- The new query matches the previous one exactly. A different table alias or lowercase versus uppercase keywords is enough to prevent reuse. - The query has no non-reusable functions such as UUID_STRING, RANDOM or RANDSTR. - The query has no external functions. - The query doesn't select from hybrid tables. - The table data hasn't changed. - The earlier persisted result is still available. - The role has the required privileges.
Even when all conditions are met, reuse is not guaranteed. Result reuse is on by default and is controlled by the USE_CACHED_RESULT parameter.
The warehouse cache is lost when the warehouse suspends, which makes auto-suspend a performance setting as well as a cost setting. A warehouse that suspends between frequent, similar queries throws away the cache that would have sped them up. On the other hand, a running warehouse consumes credits even when it is idle. Snowflake's guidelines follow from that trade-off:
| Workload | Recommended auto-suspend | Reason |
|---|---|---|
| Tasks | Immediate suspension | No cache benefit between runs |
| DevOps, DataOps, Data Science | About 5 minutes | Ad-hoc, unique queries gain little from the cache |
| Query warehouses (BI, SELECT) | At least 10 minutes | Keeps the cache warm for users |
Fit the setting to the actual query rhythm. If queries arrive only every 30 minutes, a 10-minute timeout pays for idle time and still loses the cache before the next query. To check whether a warehouse benefits from its cache at all, measure the share of scanned bytes that came from cache:
SELECT warehouse_name
,COUNT(*) AS query_count
,SUM(bytes_scanned) AS bytes_scanned
,SUM(bytes_scanned*percentage_scanned_from_cache) AS bytes_scanned_from_cache
,SUM(bytes_scanned*percentage_scanned_from_cache) / SUM(bytes_scanned) AS percent_scanned_from_cache
FROM snowflake.account_usage.query_history
WHERE start_time >= dateadd(month,-1,current_timestamp())
AND bytes_scanned > 0
GROUP BY 1
ORDER BY 5;Checkpoint 1 of 7· Fill the gap
You want a BI warehouse to suspend after 10 minutes idle. Which value completes the SQL?
ALTER WAREHOUSE my_wh SET AUTO_SUSPEND = ? ;In SQL, AUTO_SUSPEND is given in seconds, so 10 minutes is 600. The Snowsight field takes minutes.
Source: docs.snowflake.comCheckpoint 2 of 7· Check yourself
A reporting warehouse runs one query every 30 minutes. Someone proposes auto-suspend at 10 minutes "to keep the cache warm". What is the problem?
The cache only helps if the warehouse is still running when the next query arrives. Here it suspends 20 minutes before that, so the idle minutes buy nothing.
“if a warehouse executes a query every 30 minutes, it does not make sense to set the auto-suspend setting to 10 minutes”Source: docs.snowflake.com
Checkpoint 3 of 7· Exam question
A reporting query joins an `ORDERS` table (50 million rows) to an `ORDER_ITEMS` table (400 million rows) on `order_id`. In the Query Profile, the `Join` operator reports output rows far larger than the sum of its two input row counts, and the operator's time share dominates the profile. Which two conclusions and actions are appropriate to draw from this profile evidence? (Select 2)(Select 2)
Correct answers: A, B — The output row count exceeding the combined input counts indicates a join fan-out, most likely caused by `order_id` not being unique on one side of the join.; The architect should inspect whether `order_id` is duplicated on the `ORDERS` side in an unintended way, since duplicates there would multiply rows against matching `ORDER_ITEMS` rows.
- A. An output row count larger than either input alone is the classic signature of an unintended fan-out, typically from a join key that is not as unique as the query author assumed.
- B. Checking `order_id` uniqueness on the `ORDERS` side is the concrete diagnostic step that follows from the fan-out signal, since duplicate keys there would multiply against matching item rows.
- C. Query Profile reports the actual rows produced by the join logic, not a fixed product of input sizes, so a large output specifically flags a data-quality or join-condition issue rather than expected behavior.
- D. A larger warehouse adds compute capacity but does not stop a join from multiplying rows against a non-unique key; the row explosion is a logic issue, not a sizing issue.
- E. `UNION ALL` combines rows from two queries with matching columns rather than matching rows on a key, so it does not serve the same purpose as a join and would not produce the intended report.
2.Natural clustering, clustering keys and automatic clustering
Caching speeds up repeated reads. Clustering reduces how much data each read has to scan. Snowflake generally produces well-clustered data on its own, which is natural clustering. But on very large tables, sustained DML can degrade it over time. You could re-sort the rows and reinsert them by hand, but that is cumbersome and expensive. Instead, you can define a clustering key: one or more columns or expressions that co-locate similar rows in the same micro-partitions. That lets queries skip micro-partitions that don't match their filters. You can define the key in CREATE TABLE or with ALTER TABLE, and you can change or drop it later. Clustering keys can't be defined on hybrid tables.
After the key is defined, Snowflake keeps the table clustered automatically (automatic clustering). It reclusters only when the table will benefit. Those reclustering compute resources consume credits, so clustering isn't meant for every table. Signs that a table needs a key are queries that are slower than expected or have degraded over time, and a large clustering depth. Clustering pays off best on multi-terabyte tables with selective or sorting queries that mostly use the same columns. To keep costs down, choose tables that are queried often and changed rarely, and group the DML into large, infrequent batches.
Key selection rules: use at most 3–4 columns or expressions. Start with the columns most used in selective filters, such as a date column on a fact table, and then consider join columns. Cardinality matters in both directions. A Boolean column such as IS_NEW_CUSTOMER prunes almost nothing. A nanosecond timestamp is too unique to group rows well and is expensive to maintain. For a very high-cardinality column, cluster on an expression that preserves the column's ordering, for example a truncation.
Checkpoint 4 of 7· Check yourself
An events table of several TB is mostly filtered on event_ts, a nanosecond-precision timestamp. Which clustering key approach does Snowflake recommend?
Very high cardinality makes clustering expensive and ineffective. An order-preserving expression reduces the number of distinct values and still keeps min/max pruning working.
“defining the key as an expression on the column, rather than on the column directly, to reduce the number of distinct values”Source: docs.snowflake.com
Sources4
3.Search optimization service for selective lookups
A table can have only one clustering key, which leaves highly selective lookups on other columns unserved. The search optimization service (SOS) covers that case. It targets point lookups, meaning queries that return one or a few distinct rows. It also accelerates substring and regex searches, SEARCH and SEARCH_IP text and IP-address searches, predicates on semi-structured and structured columns, and selected geospatial functions. It works by building a persistent search access path that records which micro-partitions might contain each value, so the remaining micro-partitions can be skipped.
A background maintenance service builds the access path and keeps it current as data changes. You don't create a warehouse for it, but its storage and compute are billed. Queries aren't accelerated until the path is fully built. Before you benchmark, check the search_optimization_progress column of SHOW TABLES. Predicate form matters too. A cast on the constant still qualifies, but a cast on the column, such as CAST(c2 AS NUMBER) = 2, doesn't.
ALTER TABLE test_table ADD SEARCH OPTIMIZATION;Checkpoint 5 of 7· Put it in order
Put these steps for a valid search optimization benchmark in order
- 1.Let the maintenance service build the search access path in the background
- 2.Run ALTER TABLE ... ADD SEARCH OPTIMIZATION
- 3.Confirm in SHOW TABLES that search_optimization_progress shows the table fully optimized
- 4.Re-run the point-lookup queries and compare execution times
Queries aren't accelerated until the access path is fully built, so you have to confirm progress before measuring.
“make sure this column shows that the table has been fully optimized”Source: docs.snowflake.com
Checkpoint 6 of 7· Check yourself
On a search-optimized table where c2 is STRING, which query can use search optimization?
In c2 = 2, the implicit cast applies to the constant, so the predicate qualifies. Casting the column disqualifies it.
“the implicit cast is on the constant, not the column”Source: docs.snowflake.com
Sources5
4.Choosing an optimization and its cost impact
Snowflake offers four query optimizations: search optimization, query acceleration, materialized views, and clustering. Pick by query shape. Search optimization, materialized views and clustering each carry storage and compute cost in the docs' cost table. Query acceleration is billed differently. Its credits are billed by the second, only while the service is in use, and separately from warehouse usage. The QUERY_ACCELERATION_MAX_SCALE_FACTOR property caps how much compute a warehouse can lease for it. For clustering, the compute used for reclustering consumes credits, which is why keys suit tables that are queried often and changed rarely. The options can also be combined. Search optimization and query acceleration are complementary: SOS first prunes micro-partitions, and then QAS offloads part of the remaining work. Materialized views help only for the rows and columns they contain. They can, however, give the same source table a different clustering key, or store flattened VARIANT data so it is flattened only once.
| Feature | Supported query types | Note |
|---|---|---|
| Search optimization service | Equality, substring/regex, text and IP, VARIANT and structured elements, GEOGRAPHY | Storage and compute cost |
| Query acceleration service | Queries with filters or aggregation; LIMIT needs ORDER BY | Works well with ad-hoc analytics and large scans with selective filters |
| Materialized views | Equality, range, sort | Only helps the rows and columns it includes |
| Clustering the table | Equality, range | Only one key per table |
Checkpoint 7 of 7· Match them up
Match each optimization to the property that distinguishes it
Tap a term, then the definition that fits it.
Each feature targets a different query shape. Clustering's limit of one key per table is why SOS or materialized views can cover other access patterns.
“A table can be clustered only on a single key, which can contain one or more columns or expressions.”Source: docs.snowflake.com
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.ALTER WAREHOUSE ... SET AUTO_SUSPEND = 10 means ten minutes.Why is that wrong?
In SQL the auto-suspend limit is given in seconds. Ten minutes is 600.
2.A clustering key is a good default for any large table and costs nothing to maintain.Why is that wrong?
Initial clustering and ongoing maintenance consume credits. Clustering pays off only when the gain in query performance outweighs that cost.
Covered in Natural clustering, clustering keys and automatic clustering
3.Queries speed up as soon as ADD SEARCH OPTIMIZATION completes.Why is that wrong?
The search access path is built in the background, and queries aren't accelerated until it is complete.
Covered in Search optimization service for selective lookups
Practise it for real
Enable search optimization on a small table and confirm which predicates can use it
1.Create test_table with the documented CREATE OR REPLACE TABLE test_table (id INT, c1 INT, c2 STRING, c3 DATE) AS SELECT * FROM VALUES ... statement
Why: Gives you a table whose columns cover the predicate types in the docs
You should see: A five-row table, with one row of NULLs
2.Run ALTER TABLE test_table ADD SEARCH OPTIMIZATION;
Why: Adds the property that starts the maintenance service building the search access path
You should see: The statement succeeds right away while the path builds in the background
3.Run SHOW TABLES and inspect search_optimization_progress for test_table
Why: Queries aren't accelerated until the path is fully built
You should see: Progress shows the table as fully optimized before you measure anything
4.Run SELECT * FROM test_table WHERE c2 = 2; and then SELECT * FROM test_table WHERE CAST(c2 AS NUMBER) = 2;
Why: Contrasts a cast on the constant with a cast on the column
You should see: Only the first form is eligible for search optimization
Stuck? Get a nudge
On a five-row table you won't see a timing difference. The point of the exercise is the workflow and the predicate rules.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“the cache is dropped when the warehouse is suspended”
↩︎ Cache layers, cache expiration and auto-suspend“Snowflake recommends setting auto-suspend to at least 10 minutes to maintain the cache for users”
↩︎ Cache layers, cache expiration and auto-suspend“Keep in mind that a running warehouse consumes credits even if it is not processing queries.”
↩︎ Cache layers, cache expiration and auto-suspend“which is specified in seconds, not minutes”
↩︎ Exam trap 1“if a warehouse executes a query every 30 minutes, it does not make sense to set the auto-suspend setting to 10 minutes”
↩︎ Checkpoint - 2.
“For persisted query results of all sizes, the cache expires after 24 hours.”
↩︎ Cache layers, cache expiration and auto-suspend“Instead of running the query again, Snowflake simply returns the same result that it returned previously.”
↩︎ Cache layers, cache expiration and auto-suspend“The new query matches the previously executed query exactly.”
↩︎ Cache layers, cache expiration and auto-suspend“The query does not include external functions.”
↩︎ Cache layers, cache expiration and auto-suspend“The role accessing the cached results has the required privileges.”
↩︎ Cache layers, cache expiration and auto-suspend - 3.
“Percentage of data scanned from the local disk cache.”
↩︎ Cache layers, cache expiration and auto-suspend - 4.
“In general, Snowflake produces well-clustered data in tables”
↩︎ Natural clustering, clustering keys and automatic clustering“All future maintenance on the rows in the table (to ensure optimal clustering) is performed automatically by Snowflake.”
↩︎ Natural clustering, clustering keys and automatic clustering“The clustering depth for the table is large.”
↩︎ Natural clustering, clustering keys and automatic clustering“clustering is generally most cost-effective for tables that are queried frequently and do not change frequently.”
↩︎ Natural clustering, clustering keys and automatic clustering“For most tables, Snowflake recommends a maximum of 3 or 4 columns (or expressions) per key.”
↩︎ Natural clustering, clustering keys and automatic clustering“the compute resources used to perform clustering consume credits”
↩︎ Choosing an optimization and its cost impact“Clustering keys are not intended for all tables due to the costs of initially clustering the data and maintaining the clustering.”
↩︎ Exam trap 2“defining the key as an expression on the column, rather than on the column directly, to reduce the number of distinct values”
↩︎ Checkpoint - 5.
“A point lookup query returns only one or a small number of distinct rows.”
↩︎ Search optimization service for selective lookups“there is a cost for the storage and compute resources of maintenance”
↩︎ Search optimization service for selective lookups“Queries are not accelerated until the search access path has been fully built.”
↩︎ Exam trap 3“make sure this column shows that the table has been fully optimized”
↩︎ Checkpoint“the implicit cast is on the constant, not the column”
↩︎ Checkpoint - 6.
“Search optimization and query acceleration can work together to optimize query performance.”
↩︎ Choosing an optimization and its cost impact“Materialized views improve performance only for the subset of rows and columns included in the materialized view.”
↩︎ Choosing an optimization and its cost impact“A table can be clustered only on a single key, which can contain one or more columns or expressions.”
↩︎ Checkpoint - 7.
“These credits are billed separately from warehouse usage.”
↩︎ Choosing an optimization and its cost impact“The query acceleration service is billed by the second, only when the service is in use.”
↩︎ Choosing an optimization and its cost impact