DynamoDB Índices esparsos
Um índice esparso é um índice secundário que contém apenas os itens que carregam seu atributo chave - então, um subconjunto pequeno e quente de uma tabela enorme torna-se seu próprio coleção pré-filtrada e pronta para consulta.
Você tem milhões de linhas, mas a consulta executada o dia todo atinge uma pequena fatia: o tickets de suporte abertos, faturas não pagas, contas sinalizadas para revisão.
Filtrar essa fatia ainda verifica toda a tabela e cobra por cada leitura. Um o índice esparso torna o próprio índice pequeno.
O que é um índice esparso em DynamoDB?
Um índice esparso é um índice secundário que contém apenas os itens que carregam seu atributo chave. Como DynamoDB ignora qualquer item que falta nessa chave, você inventa uma chave que apenas os itens desejados escrevem – tickets abertos, faturas não pagas – e o índice se torna esse subconjunto exato. As consultas então lêem apenas, sem filtro, sem desperdício de capacidade de leitura.
- Um índice secundário indexa apenas itens que possuem sua chave. Omita a chave em um item e nunca entra no índice — sem espaço reservado, sem linha nula.
- Então você inventa uma chave que apenas os itens desejados carregam. Escreva nos itens que você consulta, remova-a do resto. O índice se torna exatamente esse subconjunto.
- A consulta lê apenas o subconjunto, sem filtro. Seu tamanho rastreia o pequeno hot definido, não o total da tabela.
REMOVEé a alavanca, não o apagamento. Uma string vazia não é um índice válido key — DynamoDB rejeita toda a gravação com uma ValidationException — então você deve exclua o atributo.
O problema: a filtragem não salva leituras
Vindo de SQL, você assume que uma cláusula WHERE restringe o trabalho. DynamoDB
FilterExpression não. Ele é executado após a leitura dos itens, não antes.
De acordo com AWS Guia do desenvolvedor, "um Query consome a mesma quantidade de capacidade de leitura, independentemente de um filtro expressão está presente" - você paga por cada item examinado e depois joga o não-jogos fora.
Portanto, se 50 dos seus 5 milhões de tickets estiverem abertos, um Query/Scan filtrado lê
através de milhões para entregar a você esses 50.
Essa é a arma por trás de cada tópico "por que meu exame é tão caro"; consulta vs. varredura tem uma visão completa do custo.
Um índice esparso evita isso, tornando o próprio índice pequeno.
Como funciona a escassez
Um índice secundário indexa apenas itens que realmente possuem a chave do índice atributos.
O documentos AWS sobre índices esparsos explique isto: DynamoDB grava um item em um índice secundário somente quando esse item carrega os atributos-chave do índice, portanto, um índice sobre um atributo raramente definido permanece naturalmente pequeno.
Perde a chave de partição (ou chave de classificação) do GSI em um item e DynamoDB simplesmente não funciona escreva-o no índice. Nenhum espaço reservado, nenhuma linha nula — o item está ausente.
Essa “ausência por defeito” é o truque. Não indexe um atributo status
que todo item carrega. Invente um atributo que apenas os itens que você deseja
consulta é transportada .
O índice então se torna uma lista limpa exatamente desses itens e um Query contra
ele lê apenas eles – sem filtro, sem desperdício de capacidade.
Imagine a tabela base alimentando o índice, onde apenas os itens que carregam a chave se cruzam:
Somente os itens codificados (abertos) são replicados no índice; itens fechados nunca entram nele.
Esta é a mesma mentalidade de formação de chaves que design de tabela única: chaves são ferramentas que você cria para um padrão de acesso específico, não espelhos fiéis de seus dados.
Um exemplo prático: "somente tickets abertos"
Pegue uma mesa de tickets de suporte. A tabela base é codificada para buscar um ticket por id e listando os tickets de um cliente:
| PK | SK | attributes |
|---|---|---|
| TICKET#a91f | DETAIL | subject, body, priority, openState |
| CUSTOMER#88 | TICKET#a91f | subject, priority, openState |
Durante a vida útil da mesa, a maioria dos tickets acaba fechada. Mas a consulta do painel seus agentes fazem o dia todo é "mostre-me todos os tickets abertos, os mais antigos primeiro" - alguns cem linhas escondidas dentro de milhões.
Defina umcom chave de partição openBucket e chave de classificação
openedAt e escreva apenas openBucket em tickets abertos. Defina-o quando o
o ticket é criado; REMOVE quando o ticket for resolvido.
| PK | SK | openBucket | openedAt | |
|---|---|---|---|---|
| TICKET#a91f | DETAIL | OPEN | 2026-06-23T09:14:00Z | ← open: in the index |
| TICKET#b02c | DETAIL | OPEN | 2026-06-22T16:40:00Z | ← open: in the index |
| TICKET#77de | DETAIL | (absent) | 2026-05-30T11:02:00Z | ← closed: NOT in the index |
Os tickets a91f e b02c carregam openBucket, então eles ficam no GSI. Bilhete
O 77de foi resolvido e o openBucket foi removido, então ele foi retirado silenciosamente. O
dashboard agora é uma consulta barata:
Query IndexName = "open-tickets-index"
KeyConditionExpression: openBucket = "OPEN"
ScanIndexForward: true # oldest first
Isso lê apenas tickets abertos. À medida que os tickets fecham, o índice encolhe por si só – seu size rastreia a população aberta, nunca o total.
Um valor de partição estática ("OPEN") é adequado aqui precisamente porque o conjunto permanece
pequeno. Um enorme conjunto aberto precisaria de uma chave de partição fragmentada, mas o "pequeno subconjunto"
index é exatamente onde um valor é a chamada correta.
A transição que faz com que funcione é uma única- removendo o atributo quando o ticket for resolvido.
Crie um protótipo da cláusula REMOVE e da condição de chave digitada para o lado de leitura no
DynamoDB Expression Builder, em vez de
montando manualmente os espaços reservados ExpressionAttributeNames e :val você mesmo.
Faça isso no DynoTable
A parte difícil de um índice esparso é ver quais itens foram incluídos nele no índice versus o qual caiu silenciosamente.
DynoTable permite alternar uma visualização de tabela para um índice secundário e ver exatamente o
subconjunto preenchido. Assim você pode confirmar que um ticket resolvido realmente foi deixado
open-tickets-index em vez de permanecer com uma chave obsoleta.

Armadilhas e próximos passos
Algumas coisas para observar:
- Remova a chave, não a deixe em branco. Uma string vazia não é uma chave de índice válida —
escrever
openBucket = ""falha com uma ValidationException, então o item nunca é indexado com ele. Para eliminar um item do índice você deveREMOVERo atributo. - O índice é. GSIs são atualizados de forma assíncrona, então um ticket recém-resolvido ainda pode aparecer brevemente — GSI lê suporta apenas consistência eventual. Não confie nisso para "este ticket está aberto agora".
- Menteatributos. Um
Queryno índice retorna apenas o atributos projetados nele. Se o painel precisar de assunto e prioridade, projete-os - ou pague umGetItemextra pelo item base completo. - Tanto GSIs quanto LSIs podem ser esparsos — a alavanca é a mesma: omita o índice chave de classificação nos itens que você não deseja indexar. Um GSI geralmente é o melhor ajuste, porém: você pode adicioná-lo após a criação da tabela e fornecer seu próprio esquema de chave e capacidade. GSI vs. LSI analisa a compensação.
Índices esparsos são uma das ideias mais antigas do modelo. O original Artigo do Amazon Dynamo de 2007 construiu a loja atendendo a padrões de acesso conhecidos e de alto volume de maneira barata.
Um índice esparso é exatamente isso: modele as chaves para que a consulta comum não leia nada. não precisa.
Para construir e inspecionar um de verdade, download DynoTable, aponte-o para sua tabela e mude a visualização de dados para seu esparso GSI - observe a atualização do subconjunto como os itens ganham e perdem a chave do índice.


