Intermedio6 min de lectura

Proyecciones de índice de DynamoDB: KEYS_ONLY, INCLUDE y ALL

Cuando creas un índice secundario, DynamoDB no copia automáticamente el elemento entero en él. Tú eliges qué se copia — la proyección del índice. Elige muy poco y tus consultas pagan una segunda lectura para buscar el resto; elige todo y pagas almacenamiento y coste de escritura extra en cada actualización. Es un compromiso que fijas una vez al crear el índice y con el que convives.

(No lo confundas con una expresión de proyección, que recorta los atributos que devuelve una sola lectura. Esta página trata sobre lo que un índice almacena físicamente — consulta expresiones de proyección para la otra.)

¿Qué es una proyección de índice de DynamoDB?

Una proyección es el conjunto de atributos que DynamoDB copia de la tabla base a un índice secundario. Eliges uno de tres tipos: KEYS_ONLY (solo las claves), INCLUDE (las claves más una lista nombrada de atributos) o ALL (el elemento completo). Más proyección significa menos lecturas de la tabla base, pero mayor coste de almacenamiento y de escritura.

  • Una proyección es el conjunto de atributos copiados en un índice secundario.
  • KEYS_ONLY — solo las claves de la tabla y del índice. La más pequeña y barata.
  • INCLUDE — las claves más una lista nombrada de atributos extra que elijas.
  • ALL — todos los atributos del elemento. La más grande; las consultas nunca necesitan la tabla base.
  • Leer un atributo que no está proyectado fuerza una lectura de la tabla base para un GSI — un coste extra silencioso. (Un LSI puede buscar atributos no proyectados por ti, con coste de lectura extra.)
  • Más proyección = más almacenamiento + más coste de escritura, ya que cada escritura en la tabla base se propaga al índice.

El problema: el índice que te hace leer dos veces

Digamos que gestionas una mesa de soporte con un GSI que te permite listar los tickets abiertos por prioridad. Proyectas KEYS_ONLY para mantenerlo ligero. La consulta devuelve rápido — pero solo te da los IDs de los tickets, y tu pantalla de cola necesita el asunto, el responsable y la antigüedad de cada ticket.

Así que ahora tu código hace una segunda ronda de lecturas contra la tabla base para hidratar cada resultado. La "única consulta" que diseñaste es en realidad una consulta más N gets, y la latencia y el coste que intentabas ahorrar volvieron de inmediato. La proyección era demasiado fina para el patrón de acceso.

Qué copia cada tipo de proyección

Base item: keys + subject +assignee + age + bodyKEYS_ONLY: keys onlyINCLUDE: keys + subject,assignee, ageALL: every attribute
  • KEYS_ONLY almacena solo la clave de la tabla base y la clave del índice. Úsalo cuando la consulta solo necesita saber qué elementos coinciden y buscarás los detalles en otro lugar — o nada en absoluto.
  • INCLUDE almacena las claves más una lista fija de atributos que nombras. El punto óptimo: proyecta exactamente los campos que tu consulta necesita renderizar, y nada más.
  • ALL copia el elemento entero. Las consultas se sirven por completo desde el índice, al coste de duplicar en él todo el almacenamiento y el rendimiento de escritura del elemento.

Para la cola de la mesa de soporte, INCLUDE con subject, assignee y age es la decisión correcta — la cola se renderiza solo desde el índice, sin una segunda lectura y sin duplicar el gran body del ticket en el índice.

El coste que estás cambiando

Cada atributo que proyectas se almacena una segunda vez y se reescribe en el índice cada vez que el elemento base cambia. Así que una proyección ALL generosa en una tabla actualizada con frecuencia multiplica tanto el almacenamiento como la capacidad de escritura. La disciplina es: proyecta lo que la consulta lee, no "todo, por si acaso".

Una sutileza que merece la pena conocer: con un índice disperso, la proyección sigue conteniendo solo los elementos que llevan la clave del índice — así que INCLUDE/ALL en un índice disperso se mantiene pequeño porque el índice en sí es pequeño. Sopesa el multiplicador de almacenamiento y escritura de tu proyección con la calculadora de precios de DynamoDB, y ensambla las consultas del índice mismas con el generador de expresiones de DynamoDB.

Ver una proyección en DynoTable

DynoTable lista cada uno de los índices secundarios de una tabla y te permite consultar directamente a través de uno. Ejecuta el mismo patrón de acceso contra la tabla base y contra un GSI y compara los resultados — los atributos que faltan en el resultado del índice son exactamente los que no proyecta, así que el efecto de una proyección es visible sin volver a leer la definición de la tabla.

Elegir a través de qué índice se ejecuta una consulta en DynoTable.
Elegir a través de qué índice se ejecuta una consulta en DynoTable.

Trampas y próximos pasos

  • Un atributo no proyectado en un GSI significa una lectura de la tabla base — diseña la proyección en torno a lo que la consulta renderiza.
  • ALL rara vez es gratis — duplica el almacenamiento y el coste de escritura; usa INCLUDE por defecto a menos que el índice necesite genuinamente todos los campos.
  • Las proyecciones son en su mayoría fijas. No puedes editar libremente la proyección de un GSI más adelante sin recrear el índice — elige deliberadamente desde el principio.
  • Relacionado: GSI vs LSI e índices dispersos determinan cuánto almacena realmente una proyección.

¿Quieres ver qué devuelve realmente cada uno de tus índices antes de rediseñarlos? Descarga DynoTable y consulta tus tablas directamente.

Actualizado