skip to content

Spectrum & External Data

Spectrum runs SQL straight over S3 files registered in the Glue Data Catalog, so cold data never has to be loaded into the cluster. Interviewers ask when to leave data external and what each such query costs.

part ofAmazon Redshiftoverview, primer and where to startread it →
on this pageshow

questions

7

In Amazon Redshift, what does Spectrum let you query, and what must you create first?

level: juniorimportance: must knowfreq 70%

answer

  1. data stays where it already lives
  2. metadata in one place, files in another
  3. a schema that points outside the cluster
  4. external schema from data catalog, plus IAM role

basics

~20 s

Redshift Spectrum runs ordinary SQL directly against files in S3 without loading them into the cluster. Before querying you create an external schema that points at a data catalog database and an IAM role, then define external tables over S3 prefixes.

solid answer

~40 s

Spectrum is the part of Amazon Redshift that reads data files left in S3. You first run `CREATE EXTERNAL SCHEMA ... FROM DATA CATALOG DATABASE '...' IAM_ROLE '...'`, which binds a Redshift schema name to a database in the AWS Glue Data Catalog (or a Hive metastore) and to an IAM role the cluster assumes to read S3 and the catalog. Inside that external schema you either see tables a Glue crawler already registered, or you write `CREATE EXTERNAL TABLE` yourself with a column list, a `STORED AS PARQUET`-style format clause and a `LOCATION` S3 prefix. From then on the table is queryable like any other, including joined to local tables — but the bytes never enter cluster storage, there is no `DISTKEY` or `SORTKEY`, and you cannot `UPDATE` or `DELETE` its rows.

code

sql · 5 lines
sql
CREATE EXTERNAL SCHEMA spectrum
FROM DATA CATALOG
DATABASE 'lake_db'
IAM_ROLE 'arn:aws:iam::123456789012:role/RedshiftSpectrumRole'
CREATE EXTERNAL DATABASE IF NOT EXISTS;

go deeper

for a junior

Be ready to say in one sentence that Spectrum queries files sitting in S3 without loading them, and that an external schema plus an IAM role is the prerequisite before any SELECT works.

for a middle

Explain the split: table metadata in the Glue Data Catalog, bytes in S3, one IAM role granting both. Know that external tables carry no distribution style, no sort key and no statistics.

for a senior

Show you have operated this: keeping partitions registered as data lands, scoping the IAM role to prefixes rather than whole buckets, and knowing which workloads must never be left external.

for a principal

Own the platform framing — whether the Glue catalog becomes the shared metadata layer several engines read, who owns table definitions, and what that standardisation buys and costs across teams.

## What Spectrum actually is Amazon Redshift stores its own tables on the cluster's compute nodes (on RA3 node types, in Redshift Managed Storage backed by S3 but owned by Redshift). **Redshift Spectrum** is a separate, AWS-managed fleet of scan workers that sits between your cluster and raw files you keep in your own S3 buckets. When a query touches an external table, the leader node compiles a plan in which the S3 portion of the work — opening files, decoding them, projecting columns, applying filters, and often partial aggregation — is dispatched to that Spectrum fleet. Only the surviving rows stream back to your compute nodes, where joins, window functions and final aggregation happen. The practical consequence: **cold or rarely-queried data never has to be loaded**. There is no `COPY` step, no duplicate copy of the data, no ingest pipeline to babysit, and the same files stay readable by Athena, EMR, Glue jobs or Spark. ## The two halves: metadata and data Spectrum needs two things that live outside Redshift. 1. **Metadata** — the table definition (columns, types, file format, partition columns, S3 location). This lives in the **AWS Glue Data Catalog**, in an Apache Hive metastore, or in a catalog Redshift creates for you. 2. **Data** — the files themselves, in an S3 bucket **in the same AWS Region as the cluster**. Cross-Region is a classic failure. You wire both up with one statement: ```sql CREATE EXTERNAL SCHEMA spectrum FROM DATA CATALOG DATABASE 'lake_db' IAM_ROLE 'arn:aws:iam::123456789012:role/RedshiftSpectrumRole' CREATE EXTERNAL DATABASE IF NOT EXISTS; ``` `spectrum` is now a schema name inside your Redshift database, but it is a *pointer*: every table you see in it is really a Glue table. The IAM role must be attached to the cluster (or namespace) and must allow the catalog reads (`glue:GetTable`, `glue:GetPartitions` and friends) plus `s3:GetObject` and `s3:ListBucket` on the data prefixes. Least privilege here matters — this role is the only thing standing between a Redshift user and every object the role can read. ## Defining external tables If a Glue crawler already registered the dataset, the tables simply appear. Otherwise you declare one: ```sql CREATE EXTERNAL TABLE spectrum.events ( event_id bigint, user_id bigint, event_type varchar(64), amount decimal(12,2) ) PARTITIONED BY (event_date date) STORED AS PARQUET LOCATION 's3://my-lake/events/'; ``` Supported formats include Parquet, ORC, Avro, JSON and delimited text. Columnar formats (Parquet, ORC) are strongly preferred because Spectrum can then read only the columns the query mentions. A partitioned external table reads **only partitions that are registered in the catalog**. New S3 prefixes are invisible until a crawler or an explicit statement adds them: ```sql ALTER TABLE spectrum.events ADD IF NOT EXISTS PARTITION (event_date='2026-08-01') LOCATION 's3://my-lake/events/event_date=2026-08-01/'; ``` Forgetting this is the single most common Spectrum bug: the query succeeds and quietly returns nothing for the new day. ## What external tables are not An external table is not a Redshift table with a different storage location. It has: - **no distribution style and no sort key** — you cannot co-locate it with a local table for a join, and there are no local zone maps; - **no column compression settings you control** — compression is whatever the files already use; - **no row-level DML** — `UPDATE` and `DELETE` do not apply; - **no automatic statistics** — the planner has no idea how big it is unless you tell it, via `ALTER TABLE spectrum.events SET TABLE PROPERTIES ('numRows'='...')`. And on a provisioned cluster, querying it is **separately billed by bytes scanned from S3**, on top of the cluster you are already paying for. That cost line is why "just leave it external" is a decision, not a default. ## Checking what you have Redshift exposes the catalog through system views: `SVV_EXTERNAL_SCHEMAS`, `SVV_EXTERNAL_TABLES`, `SVV_EXTERNAL_COLUMNS` and `SVV_EXTERNAL_PARTITIONS`. If a query returns no rows, `SVV_EXTERNAL_PARTITIONS` is the first place to look — it tells you exactly which prefixes the catalog believes exist.

  • Why can a Spectrum query against a partitioned external table return zero rows even though the files are clearly in S3?
    A partitioned external table reads only the partitions registered in the catalog. If yesterday's files landed under a new `event_date=` prefix and nothing ran `ALTER TABLE ... ADD PARTITION` or a Glue crawler, Redshift never looks at that prefix. The query succeeds and returns nothing, which makes it far more dangerous than an error.
  • What permissions does the IAM role in CREATE EXTERNAL SCHEMA actually need?
    Read access to the catalog (`glue:GetDatabase`, `glue:GetTable`, `glue:GetPartitions`) and read access to the data (`s3:GetObject` on the object prefixes, `s3:ListBucket` on the bucket, scoped by prefix condition). Grant it per-prefix, not bucket-wide — every Redshift user with rights on the external schema inherits whatever this role can read.
  • Can you create an external table in an ordinary Redshift schema?
    No. External tables exist only inside a schema created with `CREATE EXTERNAL SCHEMA`; that schema is what carries the catalog binding and the IAM role. A local schema has no way to reach S3 or Glue, so the DDL is rejected.

saying these in an interview costs you the question

  • Thinking Spectrum copies S3 data into the cluster on first query
  • Assuming external tables get a DISTKEY or SORTKEY like local tables
  • Believing new S3 files are queryable without registering the partition
  • Claiming the S3 bucket can be in any AWS Region
  • Expecting UPDATE and DELETE to work on external tables

context

open as a page

A Redshift Spectrum query is billed per terabyte scanned from S3 — what drives that number up?

level: middleimportance: must knowfreq 65%

basics

~20 s

Bytes scanned depends on how much of S3 Spectrum must actually read: row-based formats force whole-file reads, unpruned partitions add prefixes, selecting unused columns adds column chunks, and weak compression inflates every byte. Columnar files, partition filters and narrow projections all cut the bill.

open as a page

What is an Amazon Redshift federated query to RDS or Aurora, and when should you use one?

level: middleimportance: should knowfreq 40%

basics

~20 s

A federated query lets Redshift read live tables in RDS or Aurora PostgreSQL and MySQL directly, through an external schema created with FROM POSTGRES or FROM MYSQL. Use it for small, fresh operational lookups — never to scan a large transactional table.

open as a page

How does Amazon Redshift execute a join between a local table and a Spectrum external table?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Spectrum's scan layer reads, projects, filters and often partially aggregates the S3 data, then streams the surviving rows to the cluster's compute nodes. The join itself always runs on the cluster, and because external tables have no distribution key those rows must be broadcast or redistributed first.

open as a page

A partitioned Redshift Spectrum external table still scans every file — how do you diagnose it?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Compare total_partitions with qualified_partitions in SVL_S3PARTITION for the query. If all partitions qualify, the predicate is not usable for pruning — it names a data column, wraps the partition column in a function, mismatches its type, or arrives only via a join.

open as a page

How do you decide whether a dataset stays external in S3 or gets loaded into Redshift managed storage?

level: principalimportance: should knowfreq 45%

basics

~20 s

Drive it from query volume, not data volume. Data queried repeatedly by dashboards belongs in local Redshift storage where sort keys, distribution and materialized views apply; rarely-scanned history and data other engines must also read belongs in S3 behind Spectrum.

open as a page

Why can one 20 GB gzipped CSV file in S3 make a Redshift Spectrum query slow?

level: middleimportance: nice to knowfreq 35%

basics

~20 s

Gzip is not splittable, so the whole file must be decompressed sequentially by a single Spectrum reader. No matter how large the cluster, one worker does all the work, and because CSV is row-based every column is decoded too.

open as a page