Query vs Scan in DynamoDB
Query liest eine einzelne Item-Collection per Partition Key (optional verengt über
den Sort Key); Scan liest die ganze Tabelle und filtert hinterher. In der API
sehen sie ähnlich aus, aber sie berechnen — und skalieren — völlig unterschiedlich.
Wann sollte ich Query vs. Scan in DynamoDB verwenden?
Verwende Query, wann immer du die benötigte Partition benennen kannst — er liest eine einzelne Item-Collection und berechnet nur für gematchte Items. Greife auf Scan nur für einmalige Exporte oder winzige Tabellen zurück; er liest jedes Item und berechnet die gesamte Tabelle, bevor eine FilterExpression läuft. Bei echten Daten gewinnt Query.
- Query ist gezielt: du zahlst für die Items in der getroffenen Partition.
- Scan ist erschöpfend: du zahlst, um jedes Item zu lesen, und wirfst das meiste
dann mit einer
FilterExpressionweg, die nach dem berechneten Lesen läuft.
Auf einer Tabelle echter Größe ist ein Scan mit Filter die klassische „Warum ist
meine Rechnung riesig und meine Latenz schlechter als bei RDS“-Fußangel.
Gegenüberstellung
| Query | Scan | |
|---|---|---|
| Liest | Eine Partition (per PK) | Jedes Item in der Tabelle |
| Berechnete Kapazität | In der Partition getroffene Items | Ganze Tabelle, vor dem Filtern |
FilterExpression | Nach dem Lesen angewandt — Lesen wird trotzdem berechnet | Dasselbe — Filtern senkt nie Kosten |
| Latenz | Flach, während die Tabelle wächst | Wächst mit der Tabellengröße |
| Pagination | 1 MB/Seite → LastEvaluatedKey | 1 MB/Seite; parallelisierbar |
| Verwende es für | Bekannte Zugriffsmuster | Einmalige Exporte, winzige Config-Tabellen |
Die zentrale Falle: eine FilterExpression läuft nach dem berechneten Lesen durch
DynamoDB, bei beiden Operationen. Ein Scan, der „10 Zeilen zurückgibt“, kann für das
Lesen von einer Million berechnen — Filtern ist eine Bequemlichkeit, nie eine
Kostenkontrolle.
Query verwenden
Query PK = "USER#42" AND SK begins_with "ORDER#"
Wenn du zu Scan greifst, um ein häufiges Zugriffsmuster zu beantworten, ist das ein
Modellierungssignal: füge einen Global Secondary Index hinzu,
damit das Muster zu einem Query wird.
Die Entscheidung läuft auf eine Frage hinaus — kannst du die Partition benennen, die du brauchst?
Ist der Schlüssel bekannt, machst du ein Query; wenn nicht, füge einen GSI hinzu, um eines daraus zu machen, und greife nur dann auf Scan zurück, wenn kein Schlüssel passt.
Wann Scan in Ordnung ist
Einmalige Exporte, winzige Config-Tabellen und Hintergrundjobs, die bewusst durch die
ganze Tabelle blättern. Verwende Segment/TotalSegments, um einen Scan über
Worker aufzuteilen (einen parallelen Scan), wenn du wirklich alles lesen musst.
Ein reflexartiges SELECT * FROM table über DynamoDB ist dasselbe Anti-Pattern im
PartiQL-Gewand — es kompiliert zu einem Scan. Wenn du wirklich itemübergreifende
Analytik brauchst (ein GROUP BY, ein JOIN, ein Aggregat), führt DynoTables SQL
Workbench sie clientseitig über eine begrenzte Ergebnismenge aus, statt die Tabelle zu
hämmern.
Schätze die Lese-Einheiten, die jedes Muster kosten wird, mit dem Kapazitätsrechner, und probiere DynoTable, um diese Abfragen gegen deine eigenen Tabellen auszuführen und zu inspizieren.