Perché un DynamoDB Scan è lento e costoso
Un Scan legge ogni elemento nella tabella e filtra solo successivamente. Lo è
l'operazione che raggiungi dalla memoria muscolare SQL e quella in silenzio
fa aumentare il tuo conto peggiorando la latenza rispetto alla casella RDS che hai lasciato.
Perché il mio DynamoDB Scan è lento e costoso?
Un Scan legge ogni elemento nella tabella prima che venga eseguito FilterExpression, quindi
paghi per leggere l'intera tabella, non importa quante poche righe ritornano, e ottiene
più lentamente man mano che la tabella cresce. La correzione è quasi sempre una chiave Query: modella il file
modello di accesso attorno a una chiave quindi DynamoDB tocca una partizione invece di
tutto.
- Un
Scanlegge l'intera tabella, ogni volta. Le dimensioni, non il risultato, contano, decide cosa paghi e quanto tempo ci vuole. - Il
FilterExpressionè una bugia sul costo. Viene eseguito dopo la lettura misurato, quindi la restituzione di 12 articoli può comportare una fatturazione per la lettura di 12 milioni. - Un
Scandiventa più lento man mano che cresci. UnQuerycon chiave rimane piatto: si tocca una partizione, non importa quanto grande sia la tabella. - La soluzione sta quasi sempre nella modellazione, non nell'ottimizzazione. Se "Scan" per rispondere a domanda di routine, ti manca una chiave.
Cosa fa realmente un Scan
Venendo da SQL, SELECT * FROM events WHERE type = 'checkout' sembra libero —
il motore ha un indice, oppure no, ma in ogni caso ottieni le righe. Dentro
DynamoDB non esiste un pianificatore di query che lo decida per te.
Un Scan percorre l'intero tabella in sequenza, 1 MB alla volta, e distribuisce ciascuno
pagina al tuo FilterExpression. Qualunque cosa il filtro respinga viene comunque letta,
ancora misurato e ancora in bolletta. (AWS: Scansione delle tabelle)
Questa è la trappola. Il filtro assomiglia a una clausola "WHERE", ma modifica il file
set di risultati, mai il costo. Un Scan consuma la stessa capacità di lettura indipendentemente dal fatto che
non è presente alcun filtro. (AWS: Scansione delle tabelle)
Conta le unità lette
DynamoDB contatori letti (RCUs). Uno RCU compra un singolo
lettura di un item fino a 4 KB;legge costa la metà. Gli elementi più grandi vengono arrotondati ai successivi 4 KB. (AWS: modalità di capacità di lettura/scrittura)
Prendi una tabella di analisi, "ProductEvents". Ogni riga rappresenta un evento monitorato:
PK = "TENANT#acme"
SK = "TS#2026-06-23T14:08:55Z#evt_9f3a"
attrs: eventType, sessionId, userId, payloadBytesSupponiamo che contenga 2.000.000 di eventi, ciascuno di circa 1 KB, tutti sotto un unico tenant occupato. Tu voglio le casse di oggi. La mossa riflessiva:
Scan ProductEvents
FilterExpression: eventType = "checkout"
Tale filtro potrebbe restituire 40 righe. Ma il Scan legge tutti i 2.000.000 di elementi
prima. A ~1 KB ciascuno (1 RCU per 4 KB, eventualmente consistente ≈ 0,5 RCU per 4 KB),
hai misurato circa 250.000 RCUs — e sfogliato ~2 GB di dati — per
restituire 40 articoli.
Ora modella il modello di accesso come una chiave e usalo invece come Query:
Query ProductEvents
PK = "TENANT#acme"
AND SK begins_with "TS#2026-06-23"
Questo legge solo la porzione corrispondente di una partizione. Se quelle 40 righe di checkout inoltre gli altri eventi della giornata ammontano a ~2 MB, paghi per ~2 MB di letture, no 2GB. Stessa risposta, una piccola frazione del costo e la latenza rimane invariata man mano che la tabella cresce.
Scan contro Query, misurato
| Scan + filtro | Con chiave Query | |
|---|---|---|
| Legge | Ogni voce della tabella | Una partizione, ristretta da SK |
| Capacità fatturata | Tutta la tabella, prima del filtro | Solo gli elementi nella tua sezione |
| Il nostro esempio | ~250.000 RCUs (~2 GB) | qualche centinaio di RCU (~2 MB) |
| Latenza | Cresce con le dimensioni della tabella | Piatto man mano che la tabella cresce |
| Conteggio dei risultati | Non decide nulla sui costi | Corrisponde a ciò per cui paghi |
Su un Scan, il tuo risultato conta e il tuo conto lo sono
non correlato. Con un Query si inseguono a vicenda.
Decidi prima di te Scan
La maggior parte dei Scan provengono da una domanda: posso nominare la partizione I
bisogno? Se sì, è un Query. In caso negativo, la soluzione è una chiave, non un filtro più grande.
Ecco la decisione in forma di flusso.
Il percorso termina quasi sempre a Query; cadi fino a Scan solo quando no
La chiave, presente o aggiungibile, si adatta al modello di accesso.
Se lo schema è reale e ricorrente ma la tabella di base non è in grado di codificarlo, questo è vero
il segnale per aggiungere un Global Secondary Index, quindi la domanda
diventa un Query. Modellare le tue chiavi in base ai tuoi modelli di accesso in anticipo lo è
l'intero gioco: vedi design a tabella singola.
Scrivi la query con chiave, non un filtro
Quando hai bisogno di una condizione oltre la chiave, costruiscila deliberatamente anziché
scaricando tutto in un FilterExpression. Il
DynamoDB Expression Builder genera il
KeyConditionExpression e attribuisci segnaposto per te, quindi la partizione
e il tasto di ordinamento esegue il restringimento: prima di DynamoDB misura la lettura, non dopo.
KeyConditionExpression: PK = :tenant AND begins_with(SK, :day)
Quando un Scan va bene
Un Scan è il valore predefinito sbagliato per le query di routine. È lo strumento giusto quando
intendi davvero "leggere tutto":
- Esportazioni una tantum o riempimenti eseguiti manualmente.
- Piccole tabelle di configurazione/ricerca in cui l'intera tabella pesa pochi KB.
- Lavori in background che paginano apposta la tabella completa. Dividili lavoratori con "Segmento" / "TotaleSegmenti" — a — invece di una lunga scansione sequenziale. (AWS: Scansione delle tabelle)
E nota che PartiQL non ti salva: SELECT * FROM ProductEvents WHERE eventType = 'checkout' senza predicato chiave viene compilato direttamente in Scan.
È la stessa pistola con l'abbigliamento SQL. (Vedi Query vs Scan
per il resoconto completo.)
Quando hai davvero bisogno di analisi tra elementi: un "GROUP BY", un "JOIN", un aggregato
DynamoDB non può esprimere - SQL Workbench di DynoTable li esegue lato client su un
set di risultati limitato, invece di martellare la tabella con un Scan completo.
Passaggi successivi
Stima quanto costa uno dei due modelli con calcolatore dei prezzi, leggi Query vs Scan per il contrasto di livello API e download DynoTable per confrontarli con i tuoi tabelle e guardare quanti elementi legge effettivamente ciascun approccio.