DynamoDB-Index-Projektionen
Wenn du einen Secondary Index anlegst, kopiert DynamoDB das ganze Item nicht automatisch hinein. Du wählst was kopiert wird — die Projektion des Index. Zu wenig, und deine Queries zahlen einen zweiten Read für den Rest; alles, und du zahlst extra Storage und Write-Kosten bei jedem Update. Es ist ein Tradeoff, den du einmal bei der Index-Erstellung setzt und mit dem du lebst.
(Verwechsle das nicht mit einer Projection Expression, die die Attribute trimmt, die ein einzelner Read zurückgibt. Diese Seite geht um das, was ein Index physisch speichert — siehe Projection Expressions für das andere.)
Was ist eine DynamoDB-Index-Projektion?
Eine Projektion ist die Menge von Attributen, die DynamoDB aus der Base Table in
einen Secondary Index kopiert. Du wählst einen von drei Typen: KEYS_ONLY (nur
die Keys), INCLUDE (Keys plus eine benannte Attributliste) oder ALL (das
ganze Item). Mehr Projektion heißt weniger Base-Table-Fetches, aber höhere
Storage- und Write-Kosten.
- Eine Projektion ist die Menge von Attributen, die in einen Secondary Index kopiert werden.
KEYS_ONLY— nur die Table- und Index-Keys. Am kleinsten, am günstigsten.INCLUDE— die Keys plus eine benannte Liste zusätzlicher Attribute, die du wählst.ALL— jedes Attribut des Items. Am größten; Queries brauchen nie die Base Table.- Ein Attribut, das nicht projeziert ist, ist von einem GSI schlicht nicht verfügbar — deine App muss eigene Base-Table-Reads ausführen. (Nur ein LSI holt nicht-projezierte Attribute für dich nach, zu extra Read-Kosten.)
- Mehr Projektion = mehr Storage + mehr Write-Kosten, weil jeder Base-Table-Write in den Index propagiert.
Das Problem: der Index, der dich zweimal lesen lässt
Angenommen, du betreibst einen Support-Desk mit einem GSI, der offene Tickets
nach Priority listet. Du projezierst KEYS_ONLY, um ihn schlank zu halten. Die
Query kommt schnell zurück — aber sie liefert nur Ticket-IDs, und dein Queue-
Screen braucht Subject, Assignee und Age jedes Tickets.
Also macht dein Code jetzt eine zweite Runde Reads gegen die Base Table, um jedes Ergebnis zu hydratisieren. Die „eine Query“, die du designed hast, ist eigentlich eine Query plus N Gets, und Latenz und Kosten, die du sparen wolltest, sind zurück. Die Projektion war zu dünn für das Access Pattern.
Was jeder Projektionstyp kopiert
KEYS_ONLYspeichert nur den Base-Table-Key und den Index-Key. Nutze ihn, wenn die Query nur wissen muss, welche Items matchen, und du Details woanders holst — oder gar nicht.INCLUDEspeichert die Keys plus eine feste Liste benannter Attribute. Der Sweet Spot: projeziere genau die Felder, die deine Query rendern muss, und nichts mehr.ALLkopiert das gesamte Item. Queries bedienen sich vollständig aus dem Index, auf Kosten der Duplizierung von Storage und Write-Throughput des ganzen Items.
Für die Support-Desk-Queue ist INCLUDE mit subject, assignee und age der
richtige Call — die Queue rendert allein aus dem Index, ohne zweiten Fetch und
ohne den großen body des Tickets in den Index zu duplizieren.
Die Kosten, die du handelst
Jedes Attribut, das du projezierst, wird
ein zweites Mal gespeichert
und im Index neu geschrieben, wann immer das Base-Item sich ändert. Eine
großzügige ALL-Projektion auf einer häufig aktualisierten Tabelle multipliziert
also Storage und Write Capacity. Projeziere, was die Query liest, nicht „alles,
nur für den Fall“.
Eine Nuance: bei einem sparse Index hält die Projektion trotzdem nur die
Items, die den Index-Key tragen — also bleibt INCLUDE/ALL auf einem
Sparse Index klein, weil der Index selbst klein
ist. Wäge Storage- und Write-Multiplikator für deine Projektion mit dem
DynamoDB Pricing Calculator, und baue die
Index-Queries selbst mit dem
DynamoDB Expression Builder.
Eine Projektion in DynoTable sehen
DynoTable listet jeden Secondary Index einer Tabelle und lässt dich direkt durch einen querien. Fahre dasselbe Access Pattern gegen die Base Table und gegen einen GSI und vergleiche die Ergebnisse — die Attribute, die im Index-Ergebnis fehlen, sind genau die, die er nicht projeziert. So siehst du den Effekt einer Projektion, ohne die Table-Definition neu zu lesen.

Fallstricke + nächste Schritte
- Ein nicht-projeziertes Attribut auf einem GSI bedeutet einen Base-Table-Fetch — designe die Projektion um das, was die Query rendert.
ALList selten gratis — es dupliziert Storage und Write-Kosten; default zuINCLUDE, außer der Index braucht wirklich jedes Feld.- Projektionen sind weitgehend fix. Du kannst die Projektion eines GSI später nicht frei editieren, ohne den Index neu anzulegen — wähle vorne bewusst.
- Verwandt: GSI vs LSI und Sparse Indexes prägen, wie viel eine Projektion tatsächlich speichert.
Willst du sehen, was jeder deiner Indexes wirklich zurückgibt, bevor du sie umdesignst? Lade DynoTable herunter und query deine Tabellen direkt.
Hydrationskosten: KEYS_ONLY + N Gets
Zurück zum Support-Desk-Queue-Beispiel: 50 offene Tickets mit Subject, Assignee und Age angezeigt.
| Projektion | Index-Query | Follow-up-Reads | EC-RCU-Skizze (2-KB-Base-Items) |
|---|---|---|---|
KEYS_ONLY | 50 Keys zurück | 50 × GetItem | ~50 Index-RCU + ~50 Base-RCU |
INCLUDE subject, assignee, age | 50 selbstständige Rows | keine | ~50 Index-RCU only |
ALL | 50 volle Kopien | keine | ~50 Index-RCU; höherer Storage + Write-Amp |
Exakte Zahlen hängen von den Größen der projezierten Attribute ab — paste ein
Sample-Ticket in den
Item-Size Calculator und multipliziere
mit der Queue-Tiefe. INCLUDE, das nur UI-Felder listet, schlägt oft ALL, wenn
das body-Attribut groß ist und in der Listenansicht selten gezeigt wird.
LSI-Projektion und Fetch-Verhalten
Nur LSIs können optional nicht-projezierte Attribute während einer Query von
der Base Table nachholen (mit zusätzlichen Read-Kosten). GSIs tun das nie —
fehlende Attribute erfordern, dass deine App GetItem auf der Base Table aufruft.
Dieser Unterschied schiebt viele GSI-Designs zu etwas breiteren INCLUDE-
Projektionen von Anfang an.
Projektionen später ändern
GSI-Projektionen sind bei Creation fix. KEYS_ONLY zu INCLUDE zu erweitern
erfordert einen neuen Index, Backfill, Traffic-Cutover und Löschen des alten Index
— plane Felder vor dem Launch. LSIs teilen dieselbe Einschränkung.
Wenn du ein neues Access Pattern bewertest, query den Kandidaten-Index in DynoTable und liste, welche Attribute erscheinen — Lücken mapen 1:1 auf fehlende Projektionseinträge.
Mit Sparse Indexes koppeln
Ein sparse GSI, der nur Tickets mit status = open indexiert, speichert
Projektionen nur für offene Rows. INCLUDE auf diesem Index bleibt günstig, auch
wenn die Base Table Millionen geschlossener Tickets hält — der Index hat sie nie
kopiert.
Kombiniere mit Sparse-Index-Mustern, wenn die gefilterte Teilmenge relativ zur Tabelle klein ist.
Baue zuerst das Access Pattern
Nutze den Query Builder, um die GSI-Query zu prototypen — Key Condition, Projection Expression und Filter — bevor du CloudFormation änderst. Wechsle Projektionstypen in der Design-Diskussion, indem du fragst, welche Spalten die UI rendert; alles andere bleibt auf der Base Table.


