skip to content

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