

# Otimizando leituras com o pushdown no Glue ETL AWS
<a name="aws-glue-programming-pushdown"></a>

 Pushdown é uma técnica de otimização que aproxima a lógica de recuperação de dados da fonte de seus dados. A fonte pode ser um banco de dados ou um sistema de arquivos, como o Amazon S3. Ao executar determinadas operações diretamente na fonte, você pode economizar tempo e poder de processamento não levando todos os dados da rede para o mecanismo Spark gerenciado pelo AWS Glue.

Em outras palavras, o pushdown reduz as varreduras de dados. Para obter mais informações sobre o processo para identificar quando essa técnica é adequada, consulte [Reduce the amount of data scan](https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/reduce-data-scan.html) no guia *Best practices for performance tuning AWS Glue for Apache Spark jobs* em AWS Prescriptive Guidance. 

## Pushdown de predicados em arquivos armazenados no Amazon S3
<a name="aws-glue-programming-pushdown-s3"></a>

 Ao trabalhar com arquivos no Amazon S3 que foram organizados por prefixo, você pode filtrar os caminhos de destino do Amazon S3 definindo um predicado de pushdown. Em vez de ler o conjunto de dados completo e aplicar filtros em um `DynamicFrame`, você pode aplicar o filtro diretamente aos metadados da partição armazenados no catálogo de dados do AWS Glue. Essa abordagem permite listar e ler seletivamente somente os dados necessários. Para obter mais informações sobre esse processo, incluindo gravação em um bucket por partições, consulte [Gerenciar partições para saída de ETL no AWS Glue](aws-glue-programming-etl-partitions.md).

Você consegue fazer pushdown de predicados no Amazon S3 usando o parâmetro `push_down_predicate`. Considere um bucket no Amazon S3 que você particionou por ano, mês e dia. Se você quiser recuperar dados de clientes de junho de 2022, poderá instruir o AWS Glue a ler somente os caminhos relevantes do Amazon S3. Nesse caso, `push_down_predicate` é `year='2022' and month='06'`. Resumindo, a operação de leitura pode ser realizada conforme abaixo:

------
#### [ Python ]

```
customer_records = glueContext.create_dynamic_frame.from_catalog( 
    database = "customer_db", 
    table_name = "customer_tbl",
    push_down_predicate = "year='2022' and month='06'"
)
```

------
#### [ Scala ]

```
val customer_records = glueContext.getCatalogSource(
database="customer_db", 
tableName="customer_tbl", 
pushDownPredicate="year='2022' and month='06'"
).getDynamicFrame()
```

------

No cenário anterior, `push_down_predicate` recupera uma lista de todas as partições do catálogo de dados do AWS Glue e as filtra antes de ler os arquivos subjacentes do Amazon S3. Embora isso ajude na maioria dos casos, ao trabalhar com conjuntos de dados que têm milhões de partições, o processo de listar partições pode ser demorado. Para resolver esse problema, a remoção de partições do lado do servidor pode ser usada para melhorar a performance. Isso é feito criando um **índice de partição** para seus dados no catálogo de dados do AWS Glue. Para obter mais informações sobre particionamento, consulte [Criar índices de partição](partition-indexes.md). Depois, você pode usar a opção `catalogPartitionPredicate` para referenciar o índice. Para obter um exemplo de recuperação de partições com `catalogPartitionPredicate`, consulte [Filtragem do lado do servidor usando predicados de partição de catálogo](aws-glue-programming-etl-partitions.md#aws-glue-programming-etl-partitions-cat-predicates).

## Pushdown ao trabalhar com fontes JDBC
<a name="aws-glue-programming-pushdown-jdbc"></a>

O leitor de JDBC do AWS Glue usado no `GlueContext` é compatível com pushdown em bancos de dados compatíveis, fornecendo consultas SQL personalizadas que podem ser executadas diretamente na fonte. Isso pode ser feito definindo o parâmetro `sampleQuery`. Sua consulta de amostra pode especificar quais colunas selecionar, bem como fornecer um predicado de pushdown para limitar os dados transferidos para o mecanismo Spark.

Por padrão, as consultas de amostra operam em um único nó, o que pode resultar em falhas de trabalho ao lidar com grandes volumes de dados. Para usar esse atributo para consultar dados em grande escala, você deve configurar o particionamento de consultas definindo `enablePartitioningForSampleQuery` como verdadeiro, o que distribuirá a consulta para vários nós em uma chave de sua escolha. O particionamento de consultas também requer alguns outros parâmetros de configuração necessários. Para obter mais informações sobre particionamento de consultas, consulte [Leitura de tabelas JDBC em paralelo](run-jdbc-parallel-read-job.md).

Ao configurar `enablePartitioningForSampleQuery`, o AWS Glue combinará seu predicado de pushdown com um predicado de particionamento ao consultar seu banco de dados. A `sampleQuery` deve terminar com um `AND` para o AWS Glue anexar as condições de particionamento. (Se você não fornecer um predicado de pushdown, a `sampleQuery` deverá terminar com um `WHERE`). Veja um exemplo abaixo, em que fizemos o pushdown de um predicado para recuperar somente linhas com `id` maiores do que 1000. Essa `sampleQuery` retornará somente as colunas de nome e localização das linhas em que `id` for maior que o valor especificado:

------
#### [ Python ]

```
sample_query = "select name, location from customer_tbl WHERE id>=1000 AND"
customer_records = glueContext.create_dynamic_frame.from_catalog(
    database="customer_db",
    table_name="customer_tbl",
    sample_query = "select name, location from customer_tbl WHERE id>=1000 AND",

    additional_options = { 
                           "hashpartitions": 36 , 
                           "hashfield":"id",
                           "enablePartitioningForSampleQuery":True, 
                           "sampleQuery":sample_query
                          }
)
```

------
#### [ Scala ]

```
val additionalOptions = Map( 
        "hashpartitions" -> "36", 
        "hashfield" -> "id", 
        "enablePartitioningForSampleQuery" -> "true", 
        "sampleQuery" -> "select name, location from customer_tbl WHERE id >= 1000 AND"
        )
 
    val customer_records = glueContext.getCatalogSource(
        database="customer_db", 
        tableName="customer_tbl").getDynamicFrame()
```

------

**nota**  
Se `customer_tbl` tiver um nome diferente no Catálogo de Dados e no datastore subjacente, você deverá fornecer o nome da tabela subjacente em sample\_query, pois a consulta é transmitida para o datastore subjacente.

Você também pode consultar tabelas JDBC sem fazer a integração com o catálogo de dados do AWS Glue. Em vez de fornecer o nome de usuário e a senha como parâmetros para o método, você pode reutilizar as credenciais de uma conexão preexistente fornecendo e `useConnectionProperties` e `connectionName`. Neste exemplo, recuperamos as credenciais a partir de uma conexão denominada `my_postgre_connection`.

------
#### [ Python ]

```
connection_options_dict = {
    "useConnectionProperties": True,
    "connectionName": "my_postgre_connection",
    "dbtable":"customer_tbl",
    "sampleQuery":"select name, location from customer_tbl WHERE id>=1000 AND",
    "enablePartitioningForSampleQuery":True,
    "hashfield":"id",
    "hashpartitions":36
    }

customer_records = glueContext.create_dynamic_frame.from_options(
    connection_type="postgresql",
    connection_options=connection_options_dict
    )
```

------
#### [ Scala ]

```
val connectionOptionsJson = """
      {
        "useConnectionProperties": true,
        "connectionName": "my_postgre_connection",
        "dbtable": "customer_tbl",
        "sampleQuery": "select name, location from customer_tbl WHERE id>=1000 AND",
        "enablePartitioningForSampleQuery" : true,
        "hashfield" : "id",
        "hashpartitions" : 36
      }
    """
    
    val connectionOptions = new JsonOptions(connectionOptionsJson)
    
    val dyf = glueContext.getSource("postgresql", connectionOptions).getDynamicFrame()
```

------

## Notas e limitações para pushdown no AWS Glue
<a name="aws-glue-programming-pushdown-other"></a>

Pushdown, como conceito, é aplicável ao ler de fontes que não são de streaming. O AWS Glue é compatível com uma variedade de fontes; a capacidade de pushdown depende da fonte e do conector.
+ Ao se conectar ao Snowflake, você pode usar a opção `query`. Existe uma funcionalidade semelhante no conector do Redshift no AWS Glue 4.0 e versões posteriores. Para obter mais informações sobre como doe Snowflake com `query`, consulte [Ler das tabelas do Snowflake](aws-glue-programming-etl-connect-snowflake-home.md#aws-glue-programming-etl-connect-snowflake-read). 
+ O leitor de ETL do DynamoDB não é compatível com filtros ou predicados de aplicação. O MongoDB e o DocumentDB também não são compatíveis com esse tipo de funcionalidade.
+ Ao ler dados armazenados do Amazon S3 em formatos de tabela aberta, o método de particionamento para arquivos no Amazon S3 não é mais suficiente. Para ler e gravar de partições usando formatos de tabela aberta, consulte a documentação do formato.
+ Os métodos DynamicFrame não executam o pushdown de projeção do Amazon S3. Todas as colunas serão lidas nos arquivos que passam pelo filtro de predicados.
+ Ao trabalhar com conectores `custom.jdbc` no AWS Glue, a capacidade de executar o pushdown depende da fonte e do conector. Consulte a documentação apropriada do conector para confirmar se e como ele é compatível com pushdown no AWS Glue.