Query vs Scan en DynamoDB
Query lee una única colección de Items por clave de partición (acotando
opcionalmente por la clave de ordenación); Scan lee la tabla entera y filtra
después. Se parecen en la API, pero facturan —y escalan— de forma completamente
diferente.
¿Cuándo debo usar Query vs Scan en DynamoDB?
Usa Query siempre que puedas identificar la partición que necesitas — lee una única colección de Items y factura solo por los Items coincidentes. Recurre a Scan únicamente para exportaciones puntuales o tablas pequeñas; lee cada Item y factura la tabla entera antes de que se ejecute cualquier FilterExpression. Con datos reales, Query siempre gana.
- Query es dirigido: pagas por los Items de la partición coincidente.
- Scan es exhaustivo: pagas por leer cada Item y luego descartas la mayoría con
un
FilterExpressionque se ejecuta después de medir la lectura.
En una tabla de cualquier tamaño real, un Scan con filtro es el clásico footgun
del estilo «por qué mi factura es enorme y mi latencia es peor que la de RDS».
En paralelo
| Query | Scan | |
|---|---|---|
| Lecturas | Una partición (por PK) | Cada Item de la tabla |
| Capacidad facturada | Items coincidentes en la partición | Tabla entera, antes de filtrar |
FilterExpression | Aplicado tras la lectura —aún se factura la lectura | Igual —filtrar nunca reduce el coste |
| Latencia | Plana a medida que crece la tabla | Crece con el tamaño de la tabla |
| Paginación | 1 MB/página → LastEvaluatedKey | 1 MB/página; paralelizable |
| Úsalo para | Patrones de acceso conocidos | Exportaciones puntuales, tablas de config diminutas |
La trampa clave: un FilterExpression se ejecuta después de que DynamoDB mide
la lectura, en ambas operaciones. Un Scan que «devuelve 10 filas» puede facturar
por leer un millón —filtrar es una comodidad, nunca un control de coste.
Usa Query
Query PK = "USER#42" AND SK begins_with "ORDER#"
Si te ves recurriendo a Scan para responder a un patrón de acceso común, eso es
una señal de modelado: añade un Global Secondary Index para
que el patrón se convierta en un Query.
La elección se reduce a una pregunta: ¿puedes nombrar la partición que necesitas?
Si conoces la clave, haces un Query; si no, añade un GSI para convertirlo en uno,
y recurre a Scan solo cuando ninguna clave encaje.
Cuándo está bien usar Scan
Exportaciones puntuales, tablas de configuración diminutas y trabajos en segundo
plano que paginan deliberadamente por toda la tabla. Usa
Segment/TotalSegments para repartir un Scan entre workers (un scan
paralelo) cuando de verdad debas leerlo todo.
Un SELECT * FROM table reflejo sobre DynamoDB es el mismo antipatrón con ropa de
PartiQL —se compila a un Scan. Cuando de verdad necesitas analítica entre Items
(un GROUP BY, un JOIN, un agregado), el SQL Workbench de DynoTable los ejecuta
en el lado del cliente sobre un conjunto de resultados acotado en lugar de
machacar la tabla.
Estima las unidades de lectura que costará cualquiera de los dos patrones con la calculadora de capacidad, y prueba DynoTable para ejecutar e inspeccionar estas consultas contra tus propias tablas.