

# Verificar tabelas no DynamoDB
<a name="Scan"></a>

Uma operação `Scan` no Amazon DynamoDB lê cada item de uma tabela ou de um índice secundário. Por padrão, uma operação `Scan` retorna todos os atributos de dados de cada item na tabela ou índice. Você pode usar o parâmetro `ProjectionExpression` para que a operação `Scan` retorne apenas alguns dos atributos, em vez de todos eles.

`Scan` sempre retorna um conjunto de resultados. Se não forem encontrados itens correspondentes, o conjunto de resultados estará vazio.

Uma única solicitação de `Scan` pode recuperar um máximo de 1 MB de dados. Opcionalmente, o DynamoDB pode aplicar uma expressão de filtro a esses dados, restringindo os resultados antes que eles sejam retornados ao usuário.

**Topics**
+ [Expressões de filtro para verificação](#Scan.FilterExpression)
+ [Limitar o número de itens no conjunto de resultados](#Scan.Limit)
+ [Paginar resultados](#Scan.Pagination)
+ [Contar os itens nos resultados](#Scan.Count)
+ [Unidades de capacidade consumidas por verificação](#Scan.CapacityUnits)
+ [Consistência de leitura para verificação](#Scan.ReadConsistency)
+ [Verificar em paralelo](#Scan.ParallelScan)

## Expressões de filtro para verificação
<a name="Scan.FilterExpression"></a>

Se você precisar refinar ainda mais os resultados de `Scan`, existe a opção de utilizar uma expressão de filtro. Uma *expressão de filtro* determina quais itens dos resultados de `Scan` devem ser retornados para você. Todos os outros resultados serão descartados.

Uma expressão de filtro é aplicada depois que uma operação `Scan` é concluída, mas antes que os resultados sejam retornados. Portanto, uma operação `Scan` consome a mesma quantidade de capacidade de leitura, independentemente de uma expressão de filtro estar presente.

Uma operação `Scan` pode recuperar um máximo de 1 MB de dados. Esse limite se aplica antes de a expressão de filtro ser avaliada.

Com `Scan`, você pode especificar quaisquer atributos em uma expressão de filtro, incluindo atributos de chave de partição ou de chave de classificação.

A sintaxe de uma expressão de filtro é idêntica à de uma expressão de condição. As expressões de filtro podem usar os mesmos comparadores, funções e operadores lógicos que uma expressão de condição. Consulte [Expressões de condição e filtro, operadores e funções no DynamoDB](Expressions.OperatorsAndFunctions.md) para obter mais informações sobre operadores lógicos.

**Example**  
O exemplo da AWS Command Line Interface (AWS CLI) a seguir verifica a tabela `Thread` e retorna apenas os itens que foram publicados pela última vez por um usuário específico.  

```
aws dynamodb scan \
     --table-name Thread \
     --filter-expression "LastPostedBy = :name" \
     --expression-attribute-values '{":name":{"S":"User A"}}'
```

## Limitar o número de itens no conjunto de resultados
<a name="Scan.Limit"></a>

A operação `Scan` permite que você limite o número de itens retornados no resultado. Para fazer isso, defina o parâmetro `Limit` como o número máximo de itens que você deseja que a operação `Scan` retorne, antes da avaliação da expressão de filtro.

Por exemplo, suponha que você execute a operação `Scan` em uma tabela, com um valor de `Limit` igual a `6` e sem uma expressão de filtro. O resultado `Scan` contém os primeiros seis itens da tabela.

Agora suponha que você adicione uma expressão de filtro à operação `Scan`. Nesse caso, o DynamoDB aplicará a expressão de filtro aos seis itens que foram retornados e descarta os que não correspondem. O resultado final de `Scan` contém 6 itens ou menos, dependendo do número de itens que foram filtrados.

## Paginar resultados
<a name="Scan.Pagination"></a>

O DynamoDB *pagina* os resultados das operações `Scan`. Com a paginação, os resultados de `Scan` são divididos em "páginas" de dados com 1 MB de tamanho (ou menos). Uma aplicação pode processar a primeira página de resultados e, em seguida, a segunda página, e assim por diante.

Uma única operação `Scan` retorna apenas um conjunto de resultados que estão dentro do limite de tamanho de 1 MB. 

Para determinar se há mais resultados e para recuperá-los em uma página por vez, as aplicações devem fazer o seguinte:

1. Examine o resultado de `Scan` de baixo nível:
   + Se o resultado contiver um elemento `LastEvaluatedKey`, prossiga para a etapa 2.
   + Se *não* houver um `LastEvaluatedKey` no resultado, não haverá mais itens a serem recuperados.

1. Construa a nova solicitação de `Scan` com os mesmos parâmetros da anterior. No entanto, desta vez, use o valor de `LastEvaluatedKey` da etapa 1 como o parâmetro `ExclusiveStartKey` na nova solicitação de `Scan`.

1. Execute a nova solicitação de `Scan`.

1. Vá para a etapa 1.

Em outras palavras, o valor `LastEvaluatedKey` de uma resposta de `Scan` deve ser usado como `ExclusiveStartKey` da próxima solicitação de `Scan`. Se não houver um elemento `LastEvaluatedKey` em uma resposta de `Scan`, você terá recuperado a página de resultados final. (A ausência de `LastEvaluatedKey` é a única forma de você saber que chegou ao fim do conjunto de resultados.)

Você pode usar a AWS CLI para visualizar esse comportamento. A AWS CLI envia repetidamente solicitações `Scan` de baixo nível ao DynamoDB até que `LastEvaluatedKey` não esteja mais presente nos resultados. Considere o seguinte exemplo da AWS CLI que verifica toda a tabela `Movies`, mas retorna apenas os filmes de um determinado gênero.

```
aws dynamodb scan \
    --table-name Movies \
    --projection-expression "title" \
    --filter-expression 'contains(info.genres,:gen)' \
    --expression-attribute-values '{":gen":{"S":"Sci-Fi"}}' \
    --page-size 100  \
    --debug
```

Normalmente, a AWS CLI lida com a paginação automaticamente. No entanto, neste exemplo, o parâmetro AWS CLI da `--page-size` limita o número de itens por página. O parâmetro de `--debug` imprime as informações de baixo nível sobre solicitações e respostas.

**nota**  
Os resultados da paginação também serão diferentes com base nos parâmetros de entrada que você passar.   
O uso de `aws dynamodb scan --table-name Prices --max-items 1` retorna `NextToken`
O uso de `aws dynamodb scan --table-name Prices --limit 1` retorna `LastEvaluatedKey`.
Também esteja ciente de que usar`--starting-token`, em especial, requer o valor `NextToken`. 

Se você executar o exemplo, a primeira resposta do DynamoDB será semelhante ao seguinte:

```
2017-07-07 12:19:14,389 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":7,"Items":[{"title":{"S":"Monster on the Campus"}},{"title":{"S":"+1"}},
{"title":{"S":"100 Degrees Below Zero"}},{"title":{"S":"About Time"}},{"title":{"S":"After Earth"}},
{"title":{"S":"Age of Dinosaurs"}},{"title":{"S":"Cloudy with a Chance of Meatballs 2"}}],
"LastEvaluatedKey":{"year":{"N":"2013"},"title":{"S":"Curse of Chucky"}},"ScannedCount":100}'
```

O `LastEvaluatedKey` na resposta indica que nem todos os itens foram recuperados. A AWS CLI emite outra solicitação de `Scan` para o DynamoDB. Essa solicitação e o padrão de resposta continuam, até a resposta final.

```
2017-07-07 12:19:17,830 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":1,"Items":[{"title":{"S":"WarGames"}}],"ScannedCount":6}'
```

A ausência de `LastEvaluatedKey` indica que não há mais itens a serem recuperados.

**nota**  
Os AWS SDKs lidam com as respostas de baixo nível do DynamoDB (incluindo a presença ou a ausência de `LastEvaluatedKey`) e fornecem várias abstrações para paginar os resultados de `Scan` Por exemplo, a interface do documento SDK para Java fornece o suporte a `java.util.Iterator` para que você possa abordar um resultado de cada vez.  
Para obter exemplos de código em várias linguagens de programação, consulte o [Guia de conceitos básicos do Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/) e a documentação do AWS SDK para sua linguagem.

## Contar os itens nos resultados
<a name="Scan.Count"></a>

Além dos itens que correspondem aos seus critérios, a resposta de `Scan` contém os elementos a seguir:
+ `ScannedCount`: o número de itens avaliados antes de qualquer `ScanFilter` ser aplicado. Um valor alto de `ScannedCount` com poucos ou nenhum resultado de `Count` indica uma operação `Scan` ineficiente. Se você não tiver usado um filtro na solicitação, `ScannedCount` será o mesmo que `Count`. 
+ `Count`: o número de itens que permaneceram *depois* que uma expressão de filtro (se alguma) foi aplicada.

**nota**  
Se você não usar uma expressão de filtro, `ScannedCount` e `Count` terão o mesmo valor.

Se o tamanho do conjunto de resultados de `Scan` for maior que 1 MB, `ScannedCount` e `Count` representarão apenas uma contagem parcial do total de itens. Você precisa executar várias operações `Scan` para recuperar todos os resultados (consulte [Paginar resultados](#Scan.Pagination)).

Cada resposta de `Scan` contém os valores de `ScannedCount` e de `Count` dos itens que foram processados pela solicitação de `Scan` específica. Para obter os totais gerais de todas as solicitações de `Scan`, você pode manter um total em execução de `ScannedCount` e de `Count`.

## Unidades de capacidade consumidas por verificação
<a name="Scan.CapacityUnits"></a>

Você pode executar `Scan` em qualquer tabela ou índice secundário. As operações `Scan` consomem unidades de capacidade de leitura da seguinte forma.


****  

| Se você executar uma operação `Scan`... | O DynamoDB consumirá unidades de capacidade de leitura de... | 
| --- | --- | 
| Tabela | A capacidade de leitura provisionada da tabela. | 
| Índice secundário global | A capacidade de leitura provisionada do índice. | 
| Índice secundário local | A capacidade de leitura provisionada da tabela-base. | 

**nota**  
Atualmente, o acesso entre contas para operações de verificação de índice secundário não é aceito em [políticas baseadas em recursos](access-control-resource-based.md).

Por padrão, uma operação `Scan` não retorna quaisquer dados sobre quanta capacidade de leitura ela consome. Entretanto, você pode especificar o parâmetro `ReturnConsumedCapacity` em uma solicitação de `Scan` para obter essas informações. A seguir estão as configurações válidas de `ReturnConsumedCapacity`:
+ `NONE`: nenhum dado de capacidade consumida é retornado. (Esse é o padrão.)
+ `TOTAL`: a resposta inclui o número agregado de unidades de capacidade de leitura consumidas.
+ `INDEXES`: a resposta mostra o número agregado de unidades de capacidade de leitura consumidas, junto com a capacidade consumida para cada tabela e índice acessados.

O DynamoDB calcula o número de unidades de capacidade de leitura consumidas com base na quantidade e no tamanho desses itens, não na quantidade de dados exibidos para uma aplicação. Por esse motivo, o número de unidades de capacidade consumidas será o mesmo, independentemente de você solicitar todos os atributos (o comportamento padrão) ou apenas alguns deles (usando uma expressão de projeção). O número também é o mesmo, independentemente de você usar ou não uma expressão de filtro. `Scan` consome uma unidade de capacidade mínima de leitura para realizar uma leitura altamente consistente por segundo ou duas leituras finais consistentes por segundo para um item de até 4 KB. Se você precisar ler um item com mais de 4 KB, o DynamoDB precisará de unidades de solicitação de leitura adicionais. Tabelas vazias e tabelas muito grandes que têm uma quantidade esparsa de chaves de partição podem ter algumas RCUs adicionais cobradas além da quantidade de dados verificados. Isso cobre o custo de atender à solicitação `Scan`, mesmo que não existam dados.

## Consistência de leitura para verificação
<a name="Scan.ReadConsistency"></a>

Uma operação `Scan` executa leituras finais consistentes, por padrão. Isso significa que os resultados de `Scan` talvez não reflitam as alterações causadas pelas operações `PutItem` ou `UpdateItem` concluídas recentemente. Para obter mais informações, consulte [Consistência de leitura do DynamoDB](HowItWorks.ReadConsistency.md).

Se você precisar de leituras altamente consistentes, como a hora em que a operação `Scan` começa, defina o parâmetro `ConsistentRead` como `true` na solicitação de `Scan`. Isso garante que todas as operações de gravação que foram concluídas antes de `Scan` ter começado sejam incluídas na resposta de `Scan`. 

Pode ser útil configurar `ConsistentRead` como `true` no backup da tabela ou em cenários de replicação, juntamente com o [Amazon DynamoDB Streams](./Streams.html). Primeiro, você usa `Scan` com `ConsistentRead` definida como true para obter uma cópia consistente dos dados na tabela. Durante a operação `Scan`, o DynamoDB Streams registra qualquer atividade de gravação adicional que ocorra na tabela. Após a conclusão de `Scan`, você pode aplicar a atividade de gravação do fluxo à tabela.

**nota**  
Uma operação `Scan` com `ConsistentRead` definida como `true` consome duas vezes mais unidades de capacidade de leitura, em comparação com deixar `ConsistentRead` com seu valor padrão (`false`).

## Verificar em paralelo
<a name="Scan.ParallelScan"></a>

Por padrão, a operação `Scan` processa os dados sequencialmente. O Amazon DynamoDB retorna os dados para a aplicação em incrementos de 1 MB, e uma aplicação realiza operações `Scan` adicionais para recuperar os próximos 1 MB de dados. 

Quanto maior a tabela ou índice que está sendo verificado, mais tempo a operação `Scan` levará para ser concluída. Além disso, uma operação `Scan` sequencial talvez nem sempre consiga utilizar totalmente a capacidade de throughput de leitura provisionada: embora o DynamoDB distribua os dados de uma tabela grande entre várias partições físicas, uma operação `Scan` pode ler apenas uma partição de cada vez. Por esse motivo, o throughput de uma operação `Scan` é restrita pelo throughput máximo de uma única partição.

Para solucionar esses problemas, a operação `Scan` pode dividir logicamente uma tabela ou um índice secundário em vários *segmentos*, com vários operadores da aplicação verificando os segmentos em paralelo. Cada operador pode ser um thread (em linguagens de programação que aceitam multithreading) ou um processo do sistema operacional. Para executar uma verificação em paralelo, cada operador emite sua própria solicitação de `Scan` com os seguintes parâmetros:
+ `Segment`: um segmento a ser verificado por um determinado operador. Cada operador deve usar um valor diferente para `Segment`.
+ `TotalSegments`: o número total de segmentos para a verificação em paralelo. Esse valor deve ser o mesmo que o número de operadores que sua aplicação usará.

O diagrama a seguir mostra como uma aplicação multithread executa uma operação `Scan` em paralelo com três níveis de paralelismo:

![\[Uma aplicação multithread que executa uma verificação paralela, dividindo uma tabela em três segmentos.\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/ParallelScan.png)




Neste diagrama, a aplicação gera três threads e atribui um número a cada thread. (Segmentos são baseados em zero, portanto, o primeiro número é sempre 0.) Cada thread emite uma solicitação de `Scan`, configurando `Segment` como seu número designado e `TotalSegments` como 3. Cada thread verifica seu segmento designado, recuperando 1 MB de dados por vez, e retorna os dados para o thread principal da aplicação.

O DynamoDB atribui itens a *segmentos* aplicando uma função hash à chave de partição de cada item. Para determinado valor `TotalSegments`, todos os itens com a mesma chave de partição são sempre atribuídos ao mesmo `Segment`. Isso significa que, em uma tabela em que o *Item 1*, o *Item 2* e o *Item 3* compartilham `pk="account#123"` (mas têm chaves de classificação diferentes), esses itens serão processados pelo mesmo trabalhador, independentemente dos valores da chave de classificação ou do tamanho da *coleção de itens*.

Como a atribuição de *segmentos* é baseada somente no hash da chave de partição, os segmentos podem ser distribuídos de forma desigual. Alguns segmentos podem não conter itens, enquanto outros podem conter muitas chaves de partição com grandes coleções de itens. Como resultado, aumentar o número total de segmentos não garante uma performance mais rápida de verificação, especialmente quando as chaves de partição não são distribuídas de modo uniforme no espaço de teclas.

Os valores para `Segment` e `TotalSegments` aplicam-se a solicitações de `Scan` individuais, e você pode usar valores diferentes a qualquer momento. Talvez você precise experimentar com esses valores, e o número de operadores que usa, até que seu aplicativo atinja a melhor performance.

**nota**  
Uma operação Scan em paralelo com um grande número de operadores pode facilmente consumir todo o throughput provisionado da tabela ou índice que está sendo verificado. É melhor evitar tais verificações, se a tabela ou índice também incorrer em uso intensivo de atividades de leitura ou de gravação de outras aplicações.  
Para controlar a quantidade de dados retornados por solicitação, use o parâmetro `Limit`. Isso pode ajudar a evitar situações em que um operador consome todo o throughput provisionado, às custas de todos os outros operadores.