Pro ยท Lesson 7 of 9
Separate queue time, scan time, and data movement. Automatic WLM and materialized views come after the query is honest.
Sign in to save your place.
A slow query is either waiting in line, reading too much, or moving data between slices. Workload management is the line. Sort and encoding are how much gets read. Distribution is how often slices pass plates. A result cache is a plate that was already served, useful only if the question did not change.
Read SYS_QUERY_HISTORY and the query plan. EXPLAIN shows the planned slices and joins. A long time spent in a queue is workload management, not a missing sort key. Automatic WLM is the right start: short queries and long queries get separate slots, and you add a query monitoring rule when one pattern must be aborted or hopped.
Concurrency scaling adds transient capacity for queued queries on clusters that support it. It is a pressure valve, not a design. If every dashboard queues at 9am, the dashboards are doing too much work, or the schedule is stacked.
EXPLAIN
SELECT customer_id, SUM(amount)
FROM analytics.orders
WHERE ordered_at >= DATE '2026-01-01'
GROUP BY 1;A materialized view stores the result of a heavy aggregation. Refresh it on a schedule you can explain. Querying the view is then a read of a smaller table. The result cache can skip work when the same SQL returns and the underlying data has not changed. Do not design a dashboard that depends on the cache being warm. Write SQL that is cheap enough when the cache misses.
| Symptom | Likely layer | First check |
|---|---|---|
| Queued, not running | WLM | Queue time in the history view |
| Scanning most of a sorted table | Sort key or filter | EXPLAIN and the WHERE clause |
| High network or redistribute | Distribution | Join keys versus DISTKEY |
| Fine alone, slow at 9am | Concurrency | How many dashboards start together |
A slow query is waiting, reading too much, or recomputing something it already knew.
Step 1 of 3Workload management may hold a query until a slot is free. Check queue time before tuning the SQL.
SELECT query_id, queue_time, execution_time FROM sys_query_history ORDER BY start_time DESC LIMIT 20;
Step 2 of 3Reading far more blocks than needed is the most common cause. A sort key and a selective filter let Redshift skip blocks.
WHERE event_time >= '2026-10-01' -- with SORTKEY(event_time)
Step 3 of 3If the same query runs again and the data has not changed, Redshift returns the cached result without running it.
SET enable_result_cache_for_session TO on;
Explain one aggregation. Write down whether you expect a queue, a large scan, or a redistribute. Then look at a recent row in SYS_QUERY_HISTORY and see which of those the warehouse recorded. Change the SQL before you change the cluster size.
Checked against vendor documentation in October 2026. Screens and plan names still change, so confirm the control in your own instance.