Reads filtering stage.Users by email keep flagging amber — index it, and FROM "stage.Users"."byEmail" WHERE email = … becomes a key-condition Query.
CREATE GSI "byEmail" ON "stage.Users" PARTITION KEY (email) PROJECT ALL Add a GSI — an alternate key shape over the same table, and the standing fix for a read that keeps flagging amber: index the attribute you filter by, and the filter becomes a key condition. Lowers to UpdateTable; DynamoDB auto-backfills the index from existing attributes (no item rewrite), and it's queryable once ACTIVE.
CREATE GSI "name" ON "table" PARTITION KEY (attr[, attr…]) -- up to 4, types default STRING [SORT KEY (attr[, attr…])] -- up to 4; per-attr type: createdAt N PROJECT ALL | KEYS | INCLUDE (a, b)-- accepted spellings: CREATE GLOBAL SECONDARY INDEX · CREATE INDEX PROJECT chooses what rides along: ALL (every attribute), KEYS (just the keys), or INCLUDE (a, b) (keys plus the named attributes). Guides: Tables, indexes & replicas for the statement, Targeted reads for the multi-key Query rule.
Reads filtering stage.Users by email keep flagging amber — index it, and FROM "stage.Users"."byEmail" WHERE email = … becomes a key-condition Query.
CREATE GSI "byEmail" ON "stage.Users" PARTITION KEY (email) PROJECT ALL Region + tenant as partition attributes, status + date as sort attributes — kept separate and typed, not mashed into one region#tenant#status string you parse back out.
CREATE GSI "byRegionStatus" ON "stage.Orders" PARTITION KEY (region, tenant) SORT KEY (status, createdAt N) PROJECT ALL An index that answers "list titles by author" doesn't need the whole item — INCLUDE keeps the index lean and its storage bill smaller.
CREATE INDEX "byAuthor" ON "stage.Posts" PARTITION KEY (authorId) SORT KEY (publishedAt N) PROJECT INCLUDE (title, slug) Related: Tables, indexes & replicas · Targeted reads · SELECT for reading an index · Marker indexes for constraints a GSI can't enforce.