Principiante7 min di lettura

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 Scan legge 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 Scan diventa più lento man mano che cresci. Un Query con 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, payloadBytes

Supponiamo 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 + filtroCon chiave Query
LeggeOgni voce della tabellaUna partizione, ristretta da SK
Capacità fatturataTutta la tabella, prima del filtroSolo gli elementi nella tua sezione
Il nostro esempio~250.000 RCUs (~2 GB)qualche centinaio di RCU (~2 MB)
LatenzaCresce con le dimensioni della tabellaPiatto man mano che la tabella cresce
Conteggio dei risultatiNon decide nulla sui costiCorrisponde 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.

NoNoBisogna leggere gli articoliKnow the partition key?Query una partizioneCan a GSI key it?Aggiungi un GSI, quindi QueryScan ultima risorsa

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.

Aggiornato