Avançado7 min de leitura

Parallel Scans no DynamoDB

Um parallel scan divide um Scan em N requisições Scan independentes, cada uma reivindicando um Segment da tabela, para que múltiplos workers a leiam de uma vez. É a única forma de ler uma tabela inteira mais rápido do que o throughput de uma única partição permite.

O que é um parallel scan no DynamoDB?

Um parallel scan no DynamoDB divide um Scan em N requisições independentes, cada uma reivindicando um Segment da tabela via Segment e TotalSegments, para que múltiplos workers a leiam de forma concorrente. É a única forma de ler uma tabela inteira mais rápido do que o throughput de uma única partição permite — mas ainda é uma leitura completa, então você paga por cada item varrido.

  • Um Scan sequencial lê uma partição por vez — sua velocidade é limitada ao throughput de uma única partição, não importa quão grande a tabela seja.
  • Segment + TotalSegments fragmentam a leitura entre TotalSegments workers; cada worker varre sua própria fatia em paralelo.
  • O DynamoDB faz hash da partition key para atribuir segmentos, então as fatias podem ficar desequilibradas — mais workers nem sempre significa mais rápido.
  • Ainda é um Scan: você paga para ler cada item, e um parallel scan gordo pode drenar o throughput da tabela por baixo do seu tráfego ao vivo.

Por que um Scan sequencial é lento

Vindo do SQL, uma leitura de tabela inteira parece uma operação de streaming. No DynamoDB não é. Os dados da tabela vivem em muitas partições físicas, mas um único Scan as percorre uma de cada vez, 1 MB por página.

Isso significa que um Scan simples só consegue puxar do orçamento de throughput de uma partição em um dado momento — mesmo que a tabela esteja espalhada por dezenas de partições com capacidade ociosa. Quanto maior a tabela, mais devagar ele se arrasta. (AWS: Parallel scan)

Divida a leitura com Segment e TotalSegments

Um parallel scan resolve o gargalo. Você escolhe uma contagem de workers, define TotalSegments para esse número e dá a cada worker um Segment distinto baseado em zero. Cada worker dispara o próprio Scan; o DynamoDB os serve concorrentemente.

Worker 0Scan  Segment=0  TotalSegments=4
Worker 1Scan  Segment=1  TotalSegments=4
Worker 2Scan  Segment=2  TotalSegments=4
Worker 3Scan  Segment=3  TotalSegments=4

Cada worker ainda pagina com LastEvaluatedKey independentemente — ele é dono do seu segmento da primeira página à última. A aplicação costura os quatro fluxos de volta. Agora você está lendo o throughput de quatro partições de uma vez em vez de uma.

Um exemplo prático: a exportação noturna

Digamos que você roda uma tabela de telemetria, sensor-readings. Cada item é uma leitura de um dispositivo de campo:

PK = "DEVICE#a83f"          (partition key — o id do dispositivo)
SK = "TS#2026-06-22T03:14"  (sort keytimestamp ISO)
batteryMv  = 3120
tempC      = 41.8
firmwareTag = "fw-7.2.1"

Toda noite um cron job despeja a tabela inteira no S3 para o data warehouse de analytics. Um Scan sequencial de 80 GB leva horas e mal arranha sua capacidade de leitura provisionada. Então você o distribui em oito workers:

Scan  sensor-readings  Segment=0  TotalSegments=8  ConsistentRead=falseScan  sensor-readings  Segment=7  TotalSegments=8  ConsistentRead=false

Oito workers, oito segmentos, uma leitura de tabela aproximadamente oito vezes mais rápida. Se você só precisa de leituras recentes, adicione um FilterExpression para descartar timestamps antigos antes das linhas baterem na rede — monte e inspecione essa expressão no Expression Builder:

FilterExpression:  begins_with(SK, :today)

Como o DynamoDB atribui itens a segmentos

Aqui está a parte que confunde as pessoas. O DynamoDB atribui cada item a um segmento fazendo hash da sua partition key — não por contagem de linhas, não por contagem de bytes.

Então todo item que compartilha uma PK cai no mesmo segmento. Em sensor-readings, todas as leituras de DEVICE#a83f vão para um worker, independente de quantos timestamps esse dispositivo tem ou de quão grande é sua coleção de itens. (AWS: Parallel scan)

tabela sensor-readingshash da partition keySegmento 0DEVICE#a83fDEVICE#1c20Segmento 1DEVICE#9be4Segmento 2 (vazio)

A consequência: os segmentos ficam desiguais. Um worker pode ser dono de três dispositivos tagarelas com milhões de leituras; outro pode pegar uma fatia vazia. Aumentar TotalSegments não vai ajudar se suas partition keys se aglomeram — você só adiciona workers ociosos esperando pelo quente. Distribuição uniforme de chaves é o que faz o fan-out valer a pena.

Veja o custo de leitura antes de rodar

Um parallel scan é um evento de throughput, não almoço grátis. A pergunta honesta é "quantas unidades de leitura ler esta tabela inteira vai custar?" — e o DynoTable te mostra o custo de leitura medido de um scan contra sua tabela real, segmento por segmento, para que o job noturno não te surpreenda na conta.

Armadilhas e quando não vale a pena

  • O penhasco de throughput. Um scan com TotalSegments alto pode consumir a capacidade de leitura inteira da tabela em segundos, matando de fome o tráfego ao vivo. Em uma tabela servindo usuários, limite cada worker com o parâmetro Limit ou varra fora do pico. (AWS: Parallel scan)
  • Ainda é a ferramenta errada para um padrão de acesso. Parallel scans são para jobs deliberados de tabela inteira — exportações, backfills, migrações. Se você está apelando para um para responder a uma query recorrente, isso é um sinal de modelagem: adicione uma GSI e torne-a um Query.
  • SELECT * no PartiQL é o mesmo scan disfarçado. Ele compila para um Scan sequencial. Quando você realmente precisa de analytics entre itens — um GROUP BY, um JOIN, um agregado — a SQL Workbench do DynoTable roda isso no cliente sobre um conjunto de resultados delimitado, em vez de martelar a tabela.
  • Consistência forte dobra a conta. Um Scan usa por padrão leituras eventualmente consistentes. Para uma exportação, deixe ConsistentRead=false a menos que você realmente precise de um snapshot pontual.

Próximos passos

Modele suas chaves para que leituras do dia a dia nunca precisem de um scan — comece com single-table design e Query vs Scan. Quando um job de tabela inteira for genuinamente a escolha certa, experimente o DynoTable para rodar um parallel scan contra suas próprias tabelas e acompanhar o custo de leitura em tempo real.

Atualizado