

# Análisis de tablas en DynamoDB
<a name="Scan"></a>

Una operación `Scan` en Amazon DynamoDB lee todos los elementos de una tabla o de un índice secundario. De manera predeterminada, una operación `Scan` devuelve todos los atributos de datos de todos los elementos de la tabla o el índice. Puede utilizar el parámetro `ProjectionExpression` para que `Scan` solo devuelva algunos de los atributos, en lugar de todos ellos.

`Scan` siempre devuelve un conjunto de resultados. Si no se encuentran elementos coincidentes, el conjunto de resultados está vacío.

En una sola solicitud `Scan` se puede recuperar un máximo de 1 MB de datos. Si lo desea, DynamoDB puede aplicar una expresión de filtro a estos datos, para reducir los resultados antes de que se devuelvan al usuario.

**Topics**
+ [Expresiones de filtro para el análisis](#Scan.FilterExpression)
+ [Limitación del número de elementos del conjunto de resultados](#Scan.Limit)
+ [Paginación de los resultados](#Scan.Pagination)
+ [Recuento de los elementos en los resultados](#Scan.Count)
+ [Unidades de capacidad que consume el análisis](#Scan.CapacityUnits)
+ [Coherencia de lectura para el análisis](#Scan.ReadConsistency)
+ [Análisis paralelo](#Scan.ParallelScan)

## Expresiones de filtro para el análisis
<a name="Scan.FilterExpression"></a>

Si tiene que refinar más los resultados de `Scan`, si lo desea puede indicar una expresión de filtro. Una *expresión de filtro* determina qué elementos de los resultados de `Scan` se deben devolver al usuario. Todos los demás resultados se descartan.

Una expresión de filtro se aplica después de que la operación `Scan` haya finalizado, pero antes de devolver los resultados. Por consiguiente, `Scan` consume la misma cantidad de capacidad de lectura aunque se especifique una expresión de filtro.

En una operación `Scan` se puede recuperar un máximo de 1 MB de datos. Este límite se aplica antes de evaluar la expresión de filtro.

Con `Scan`, puede especificar cualquier atributo en una expresión de filtro, incluidos los atributos de clave de partición y de clave de ordenación.

La sintaxis de una expresión de filtro es la misma que la de una expresión de condición. Las expresiones de filtro pueden utilizar los comparadores, funciones y operadores lógicos que las expresiones de condición. Consulte [Expresiones, operadores y funciones de condición y filtro en DynamoDB](Expressions.OperatorsAndFunctions.md) para obtener más información sobre operadores lógicos.

**Example**  
En el siguiente ejemplo de la AWS Command Line Interface (AWS CLI) se examina la tabla `Thread` y solo se devuelven los últimos elementos publicados por un usuario determinado.  

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

## Limitación del número de elementos del conjunto de resultados
<a name="Scan.Limit"></a>

La operación `Scan` permite limitar el número de elementos que devuelve en el resultado. Para ello, establezca el parámetro `Limit` en el número máximo de elementos que desea que devuelva la operación `Scan`, antes de la evaluación de la expresión de filtro.

Por ejemplo, suponga que utiliza la operación `Scan` en una tabla con un valor de `Limit` de `6` y sin expresión de filtro. El resultado de `Scan` contiene los seis primeros elementos de la tabla.

Ahora, suponga que agrega una expresión de filtro a `Scan`. En este caso, DynamoDB aplica la expresión de filtro a los seis elementos que se hayan devuelto y descarta los que no coincidan. El resultado de `Scan` final contendrá 6 elementos o menos, según el número de elementos que el filtro elimine.

## Paginación de los resultados
<a name="Scan.Pagination"></a>

DynamoDB *pagina* los resultados de las operaciones `Scan`. La paginación permite dividir los resultados de `Scan` en "páginas" de datos con un tamaño de 1 MB (o menos). Una aplicación puede procesar la primera página de resultados, luego la segunda página, y así sucesivamente.

Una operación `Scan` única devuelve solamente un conjunto de resultados que se ajuste al límite de tamaño de 1 MB. 

Para determinar si hay más resultados y para recuperarlos de página en página, las aplicaciones deben hacer lo siguiente:

1. Examinar el resultado de `Scan` de bajo nivel:
   + Si el resultado contiene una entrada `LastEvaluatedKey`, vaya al paso 2.
   + Si *no* figura `LastEvaluatedKey` en el resultado, no hay más elementos que recuperar.

1. Crear una nueva solicitud `Scan` con los mismos parámetros que la anterior. Sin embargo, esta vez, se toma el valor `LastEvaluatedKey` del paso 1 y se usa como parámetro `ExclusiveStartKey` en la nueva solicitud `Scan`.

1. Ejecutar la nueva solicitud `Scan`.

1. Ir al paso 1.

Es decir, el valor de `LastEvaluatedKey` de la respuesta de `Scan` debe utilizarse como valor de `ExclusiveStartKey` en la siguiente solicitud `Scan`. Si no hay un componente `LastEvaluatedKey` en una respuesta de `Scan`, significa que se ha recuperado la última página de resultados. La ausencia de `LastEvaluatedKey` es la única forma de saber que se ha alcanzado el final del conjunto de resultados.

Puede utilizar la AWS CLI para ver este comportamiento. La AWS CLI envía solicitudes `Scan` de bajo nivel a DynamoDB una y otra vez hasta que `LastEvaluatedKey` ya no esté presente en los resultados. Considere el siguiente ejemplo de la AWS CLI que examina toda la tabla `Movies`, pero solo devuelve las películas de un 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, la AWS CLI se encarga de la paginación automáticamente. No obstante, en este ejemplo, el parámetro AWS CLI de la `--page-size` limita el número de elementos por página. El parámetro `--debug` muestra información de bajo nivel de las solicitudes y las respuestas.

**nota**  
Los resultados de paginación también diferirán en función de los parámetros de entrada que pase.   
El uso de `aws dynamodb scan --table-name Prices --max-items 1` devuelve un `NextToken`
El uso de `aws dynamodb scan --table-name Prices --limit 1` devuelve un `LastEvaluatedKey`.
También tenga en cuenta que usar un `--starting-token` en particular requiere el valor de `NextToken`. 

Si ejecuta el ejemplo, la primera respuesta de DynamoDB será similar a la siguiente.

```
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}'
```

El elemento `LastEvaluatedKey` de la respuesta indica que no se han recuperado todos los elementos. La AWS CLI envía entonces otra solicitud `Scan` a DynamoDB. Este patrón de solicitud y respuesta continúa hasta la respuesta final.

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

La ausencia de `LastEvaluatedKey` indica que no hay más elementos que recuperar.

**nota**  
Los SDK de AWS se encargan también de las respuestas de DynamoDB de bajo nivel (incluida la presencia o ausencia de `LastEvaluatedKey`) y proporcionan varias abstracciones para paginar los resultados de `Scan`. Por ejemplo, la interfaz de documentos de SDK para Java proporciona compatibilidad con `java.util.Iterator` para que pueda examinar los resultados de uno en uno.  
Para ver ejemplos de código en diversos lenguajes de programación, consulte la [Guía de inicio de Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/) y la documentación del SDK de AWS correspondiente a su lenguaje.

## Recuento de los elementos en los resultados
<a name="Scan.Count"></a>

Además de los elementos que coinciden con los criterios, la respuesta de `Scan` contiene las entradas siguientes:
+ `ScannedCount`: El número de elementos evaluados, antes de que se aplique cualquier `ScanFilter`. Un valor de `ScannedCount` elevado, con pocos resultados de `Count` o ninguno indica que la operación `Scan` ha sido ineficiente. Si no ha utilizado un filtro en la solicitud, `ScannedCount` es igual que `Count`. 
+ `Count`: El número de elementos restantes *después* de aplicar una expresión de filtro (si la hay).

**nota**  
Si no se utiliza una expresión de filtro, `ScannedCount` y `Count` tendrán el mismo valor.

Si el tamaño del conjunto de resultados de `Scan` es mayor que 1 MB, entonces `ScannedCount` y `Count` representarán únicamente un recuento parcial de los elementos totales. Deberá llevar a cabo varias operaciones `Scan` para recuperar todos los resultados (consulte [Paginación de los resultados](#Scan.Pagination)).

Cada respuesta de `Scan` contendrá los valores de `ScannedCount` y `Count` de los elementos que se han procesado en esa solicitud `Scan` concreta. Para obtener totales globales para todas las solicitudes `Scan`, puede llevar un recuento total de `ScannedCount` y `Count`.

## Unidades de capacidad que consume el análisis
<a name="Scan.CapacityUnits"></a>

Puede utilizar la operación `Scan` en cualquier tabla o índice secundario. Las operaciones `Scan` consumen las unidades de capacidad de lectura, como se indica a continuación.


****  

| Si `Scan` se aplica a... | DynamoDB consume unidades de capacidad de lectura de... | 
| --- | --- | 
| Tabla | La capacidad de lectura aprovisionada de la tabla. | 
| Índice secundario global | La capacidad de lectura aprovisionada del índice. | 
| Índice secundario local | La capacidad de lectura aprovisionada de la tabla base. | 

**nota**  
Las políticas [basadas en recursos](access-control-resource-based.md) no admiten actualmente el acceso entre cuentas para operaciones de análisis de índices secundarios.

De forma predeterminada, una operación `Scan` no devuelve datos sobre la cantidad de capacidad de lectura que consume. Sin embargo, puede especificar el parámetro `ReturnConsumedCapacity` en una solicitud `Scan` para obtener esta información. A continuación se muestran los ajustes válidos de `ReturnConsumedCapacity`:
+ `NONE`: no se devuelven datos de capacidad consumida. (Esta es la opción predeterminada.)
+ `TOTAL`: la respuesta incluye el número total de unidades de capacidad de lectura consumidas.
+ `INDEXES`: la respuesta muestra el número total de unidades de capacidad de lectura consumidas, así como la capacidad consumida de cada tabla e índice a los que se ha obtenido acceso.

DynamoDB calcula el número de unidades de capacidad de lectura consumidas según el número de elementos y el tamaño de dichos elementos, no según la cantidad de datos que se devuelven a una aplicación. Por este motivo, el número de unidades de capacidad consumidas es el mismo si se solicitan todos los atributos (el comportamiento predeterminado) o solo algunos de ellos (mediante una expresión de proyección). El número también es el mismo tanto si se utiliza una expresión de filtro como si no. `Scan`consume una unidad de capacidad de lectura mínima para realizar una lectura altamente coherente por segundo o dos lecturas coherentes posteriores por segundo para un elemento de hasta 4 KB. Para leer un elemento mayor que 4 KB, DynamoDB necesita unidades de solicitud de lectura adicionales. Con las tablas vacías y las tablas muy grandes con una cantidad escasa de claves de partición, es posible que se cobren algunas RCU adicionales además de la cantidad de datos analizados. Esto cubre el costo de atender la solicitud `Scan`, incluso si no hay datos.

## Coherencia de lectura para el análisis
<a name="Scan.ReadConsistency"></a>

De forma predeterminada, una operación `Scan` lleva a cabo lecturas consistentes finales. Esto significa que los resultados de `Scan` podrían no reflejar los cambios provocados por operaciones `PutItem` o `UpdateItem` realizadas recientemente. Para obtener más información, consulte [Coherencia de lectura de DynamoDB](HowItWorks.ReadConsistency.md).

Si requiere lecturas de consistencia alta desde el momento en que se inicie la operación `Scan`, establezca el parámetro `ConsistentRead` en `true` en la solicitud `Scan`. De este modo, se asegurará de que todas las operaciones de escritura que se han completado antes de iniciar `Scan` se incluyan en la respuesta de `Scan`. 

Establecer `ConsistentRead` en `true` puede resultar útil para realizar backup o replicaciones de tablas, combinado con [DynamoDB Streams](./Streams.html). En primer lugar, se utiliza `Scan` con `ConsistentRead` establecido en true para obtener una copia consistente de los datos de la tabla. Durante la operación `Scan`, DynamoDB Streams registra la actividad de escritura adicional que se produce en la tabla. Una vez que la operación `Scan` ha finalizado, puede aplicar la actividad de escritura de la secuencia a la tabla.

**nota**  
Una operación `Scan` con `ConsistentRead` establecido en `true` consumirá el doble de unidades de capacidad de lectura que si `ConsistentRead` se deja establecido en su valor predeterminado (`false`).

## Análisis paralelo
<a name="Scan.ParallelScan"></a>

De forma predeterminada, la operación `Scan` procesa los datos secuencialmente. Amazon DynamoDB devuelve los datos a la aplicación en incrementos de 1 MB y una aplicación lleva a cabo operaciones `Scan` adicionales para recuperar la siguiente franja de 1 MB de datos. 

Cuanto mayor es la tabla o el índice que se analiza, más tiempo tarda `Scan` en completarse. Además, puede que una operación `Scan` secuencial no consiga siempre utilizar plenamente la capacidad de rendimiento de lectura aprovisionada. Esto se debe a que, aunque DynamoDB distribuye los datos de las tablas grandes entre varias particiones físicas, una operación `Scan` solo puede leer una partición a la vez. Por este motivo, el desempeño de una operación `Scan` se ve restringido por el desempeño máximo de cada partición individual.

Para abordar estos problemas, la operación `Scan` puede dividir una tabla o un índice secundario lógicamente en varios *segmentos*, de tal forma que varios procesos de trabajo de la aplicación puedan examinarlos en paralelo. Cada proceso de trabajo puede ser un subproceso (en los lenguajes de programación que admiten la ejecución de múltiples subprocesos) o un proceso del sistema operativo. Para llevar a cabo un examen en paralelo, cada proceso de trabajo emite su propia solicitud `Scan` con los siguientes parámetros:
+ `Segment` segmento que un proceso de trabajo concreto examinará. Cada proceso de trabajo debe utilizar un valor diferente de `Segment`.
+ `TotalSegments` número total de segmentos del examen en paralelo. Este valor debe ser el mismo que el número de procesos de trabajo que la aplicación va a utilizar.

En el siguiente diagrama se muestra cómo una aplicación de ejecución multiproceso realiza una operación `Scan` en paralelo con tres grados de paralelismo.

![\[Aplicación de varios subprocesos que realiza un análisis paralelo dividiendo una tabla en tres segmentos.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/ParallelScan.png)




En este diagrama, la aplicación crea tres subprocesos y asigna un número a cada uno de ellos. Los segmentos parten de cero, de modo que el primer número siempre es 0. Cada subproceso emite una solicitud `Scan` y establece el valor de `Segment` en el número designado y el valor de `TotalSegments`, en 3. Cada subproceso examina su segmento designado, recupera datos en franjas de 1 MB a la vez y devuelve los datos al subproceso principal de la aplicación.

DynamoDB asigna elementos a los *segmentos* mediante la aplicación de una función hash a la clave de partición de cada elemento. Para un valor de `TotalSegments` determinado, todos los elementos con la misma clave de partición siempre se asignan al mismo `Segment`. Esto significa que en una tabla en la que *elemento 1*, *elemento 2* y *elemento 3* comparten `pk="account#123"` (pero tienen claves de clasificación diferentes), el mismo trabajador procesará estos elementos, independientemente de los valores de las claves de clasificación o del tamaño de la *recopilación de elementos*.

Como la asignación de *segmentos* se basa únicamente en el hash de la clave de partición, los segmentos pueden distribuirse de forma desigual. Es posible que algunos segmentos no contengan elementos, mientras que otros pueden contener muchas claves de partición con grandes recopilaciones de elementos. Como resultado, aumentar el número total de segmentos no garantiza un rendimiento de análisis más rápido, especialmente cuando las claves de partición no están distribuidas uniformemente en el espacio de claves.

Los valores de `Segment` y `TotalSegments` se aplican a las solicitudes `Scan` individuales; puede utilizar valores diferentes en cualquier momento. Es posible que tenga que experimentar con estos valores y con el número de procesos de trabajo utilizados hasta lograr el desempeño óptimo de la aplicación.

**nota**  
Un examen en paralelo con un gran número de procesos de trabajo puede consumir fácilmente todo el rendimiento aprovisionado de la tabla o el índice que se examina. Es preferible evitar este tipo de exámenes si la tabla o el índice también llevan a cabo una intensa actividad de lectura o escritura de otras aplicaciones.  
Para controlar la cantidad de datos devueltos por cada solicitud, utilice el parámetro `Limit`. Esto puede ayudar a evitar situaciones en las que un proceso de trabajo consume todo el desempeño provisionado a costa de todos los demás procesos de trabajo.