

# Otimizar a performance do Athena
<a name="performance-tuning"></a>

Este tópico fornece informações gerais e sugestões específicas para melhorar a performance de suas consultas do Athena e como resolver erros relacionados a limites e ao uso de recursos.

Em termos gerais, as otimizações podem ser agrupadas em categorias de serviço, consulta e estrutura de dados. As decisões tomadas no nível do serviço, sobre como você escreve suas consultas e como estrutura seus dados e tabelas, podem influenciar a performance.

**Topics**
+ [

# Otimização do uso do serviço
](performance-tuning-service-level-considerations.md)
+ [

# Otimizar consultas
](performance-tuning-query-optimization-techniques.md)
+ [

# Otimizar dados
](performance-tuning-data-optimization-techniques.md)
+ [

# Usar formatos de armazenamento colunares
](columnar-storage.md)
+ [

# Usar particionamento e bucketing
](ctas-partitioning-and-bucketing.md)
+ [

# Particionar dados
](partitions.md)
+ [

# Usar projeção de partições com o Amazon Athena
](partition-projection.md)
+ [

# Prevenir o controle de utilização do Amazon S3
](performance-tuning-s3-throttling.md)
+ [

# Recursos adicionais
](performance-tuning-additional-resources.md)

# Otimização do uso do serviço
<a name="performance-tuning-service-level-considerations"></a>

As considerações sobre o nível de serviço incluem o número de workloads que você executa por conta, as Service Quotas não apenas para o Athena, mas para todos os serviços, e o pensamento sobre como reduzir os erros de falta de recursos.

**Topics**
+ [

## Operar várias workloads na mesma conta
](#performance-tuning-service-quotas)
+ [

## Reduzir erros de "falta de recursos"
](#performance-tuning-resource-limits)

## Operar várias workloads na mesma conta
<a name="performance-tuning-service-quotas"></a>

O Athena usa cotas para limitar a simultaneidade de consultas e as taxas de solicitação de API no nível da conta. Exceder essas cotas pode gerar falhas nas consultas durante a execução ou no momento do envio. Para obter mais informações sobre essas cotas, consulte [Service Quotas](service-limits.md). 

Se você operar várias workloads na mesma conta da AWS, elas competirão pela mesma cota no nível da conta. Por exemplo, se uma workload sofrer uma explosão inesperada de consultas, outra workload em execução na mesma conta poderá ter um tempo de fila elevado ou, na pior das hipóteses, falhas no envio da consulta devido ao controle de utilização.

Recomendamos que você use o CloudWatch para monitorar a utilização do serviço por meio de gráficos e painéis. É possível também configurar alarmes do CloudWatch que emitam alertas quando a utilização se aproximar da cota de serviço para consultas simultâneas, permitindo que medidas sejam tomadas antes que os limites de cota sejam atingidos. Para obter mais informações, consulte [Monitorar métricas de uso do Athena com o CloudWatch](monitoring-athena-usage-metrics.md).

Para controlar a simultaneidade de consultas e isolar as workloads da sua conta, use reservas de capacidade. As reservas de capacidade fornecem capacidade dedicada de processamento de consultas dentro de uma única conta. A capacidade é medida em unidades de processamento de dados (DPUs) e pode ser adicionada ou removida para aumentar ou diminuir a simultaneidade de consultas, respectivamente. As reservas de capacidade permitem que você isole as workloads umas das outras dentro da conta designando capacidade a um ou mais grupos de trabalho. Para obter mais informações, consulte [Gerenciar a capacidade de processamento de consulta](capacity-management.md).

Embora você deva isolar as workloads não relacionadas em contas diferentes da AWS (como isolar o ambiente de desenvolvimento do ambiente de produção), essa abordagem não oferece uma maneira escalável de aumentar a simultaneidade de consultas. Em vez disso, use reservas de capacidade para gerenciar e escalar as necessidades de processamento de consultas dentro de uma única conta.

### Considerar as cotas em outros serviços
<a name="performance-tuning-quotas-in-other-services"></a>

Ao executar uma consulta, o Athena pode chamar outros serviços que impõem cotas. Durante a execução da consulta, o Athena pode fazer chamadas de API para o AWS Glue Data Catalog, o Amazon S3 e outros serviços da AWS, como o IAM e o AWS KMS. Se você usar [consultas federadas](federated-queries.md), o Athena também chamará o AWS Lambda. Todos esses serviços têm seus próprios limites e cotas que podem ser excedidos. Quando a execução de uma consulta encontra erros nesses serviços, ela falha e inclui o erro do serviço de origem. Os erros recuperáveis são repetidos, mas as consultas ainda poderão falhar se o problema não for resolvido a tempo. Leia atentamente as mensagens de erro para determinar se elas vêm do Athena ou de outro serviço. Alguns erros relevantes são abordados nesta seção de ajuste de desempenho.

Para obter mais informações sobre como resolver erros causados por cotas de serviço do Amazon S3, consulte [Evite ter uma quantidade muito grande de arquivos](performance-tuning-data-optimization-techniques.md#performance-tuning-avoid-having-too-many-files) mais adiante neste documento. Para obter mais informações sobre a otimização de performance do Amazon S3, consulte [Padrões de design de práticas recomendadas: otimizar a performance do Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html) no *Guia do usuário do Amazon S3*.

## Reduzir erros de "falta de recursos"
<a name="performance-tuning-resource-limits"></a>

O Athena executa consultas em um mecanismo de consulta distribuído. Quando você envia uma consulta, o planejador de consultas do mecanismo do Athena estima a capacidade computacional necessária para executar a consulta e prepara devidamente um cluster de nós de computação. Algumas consultas, como consultas DDL, são executadas em apenas um nó. Consultas complexas baseadas em grandes conjuntos de dados são executadas em clusters muito maiores. Os nós são uniformes e têm as mesmas configurações de memória, CPU e disco. O Athena aumenta a escala horizontalmente, não verticalmente, para processar consultas mais exigentes.

Às vezes, as demandas de uma consulta excedem os recursos disponíveis para o cluster que está executando a consulta. Quando isso acontece, a consulta falha com o erro Query exhausted resources at this scale factor.

O recurso que se esgota com mais frequência é a memória, mas em casos raros também pode ser o espaço em disco. Os erros de memória geralmente ocorrem quando o mecanismo executa uma função de junção ou janela, mas também podem ocorrer em contagens e agregações distintas.

Mesmo que a consulta falhe com um erro de “falta de recursos” uma vez, ela pode ter êxito ao ser executada novamente. A execução da consulta não é determinística. Fatores como o tempo necessário para carregar os dados e como os conjuntos de dados intermediários serão distribuídos pelos nós podem resultar em diferentes usos de recursos. Por exemplo, imagine uma consulta que une duas tabelas e tem uma grande distorção na distribuição dos valores da condição de junção. A consulta pode ter êxito na maioria das vezes, mas ocasionalmente falha quando os valores mais comuns acabam sendo processados pelo mesmo nó.

Para evitar que suas consultas excedam os recursos disponíveis, use as dicas de ajuste de performance mencionadas neste documento. Em particular, para obter dicas sobre como otimizar consultas que esgotam os recursos disponíveis, consulte [Otimizar junções](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-joins), [Reduzir o escopo das funções da janela ou removê-las](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-window-functions) e [Otimizar consultas com o uso de aproximações](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-queries-by-using-approximations). 

# Otimizar consultas
<a name="performance-tuning-query-optimization-techniques"></a>

Use as técnicas de otimização de consulta descritas nesta seção para fazer com que as consultas sejam executadas mais rapidamente ou como soluções alternativas para consultas que excedam os limites de recursos no Athena.

## Otimizar junções
<a name="performance-tuning-optimizing-joins"></a>

Há muitas estratégias diferentes para executar junções em um mecanismo de consulta distribuído. Duas das mais comuns são as junções hash distribuídas e as consultas com condições de junção complexas.

### Em uma junção de hash distribuída, coloque tabelas grandes à esquerda e tabelas pequenas à direita
<a name="performance-tuning-distributed-hash-join"></a>

O tipo mais comum de junção usa uma comparação de igualdade como condição de junção. O Athena executa esse tipo de junção como uma junção hash distribuída.

Em uma junção hash distribuída, o mecanismo cria uma tabela de pesquisa (tabela hash) com base em um dos lados da junção. Esse lado é chamado de *lado da compilação*. Os registros do lado da compilação são distribuídos entre os nós. Cada nó cria uma tabela de pesquisa para o respectivo subconjunto. O outro lado da junção, denominado *lado de teste*, é então transmitido pelos nós. Os registros do lado de teste são distribuídos pelos nós da mesma forma que no lado da compilação. Isso permite que cada nó realize a junção pesquisando os registros correspondentes em sua própria tabela de pesquisa.

Quando as tabelas de pesquisa criadas do lado da compilação da junção não cabem na memória, as consultas podem falhar. Mesmo que o tamanho total do lado da compilação seja menor que a memória disponível, as consultas poderão falhar se a distribuição dos registros tiver uma distorção significativa. Em um caso extremo, todos os registros poderiam ter o mesmo valor para a condição de junção e caber na memória em um único nó. Mesmo uma consulta com menos distorção poderá falhar se um conjunto de valores for enviado ao mesmo nó e a soma dos valores ultrapassar a memória disponível. Os nós têm a capacidade de vazar registros para o disco, mas o vazamento retarda a execução da consulta e pode ser insuficiente para evitar que a consulta falhe.

O Athena tenta reordenar as junções para usar a relação maior como lado de teste e a relação menor como o lado da compilação. No entanto, por não gerenciar os dados em tabelas, o Athena tem informações limitadas e muitas vezes deve presumir que a primeira tabela é a maior e a segunda tabela é a menor.

Ao gravar junções com condições de junção baseadas em igualdade, suponha que a tabela à esquerda da palavra-chave `JOIN` seja o lado de teste e que a tabela à direita seja o lado da compilação. Verifique se a tabela direita, o lado da compilação, é a menor das tabelas. Se não for possível diminuir o lado da compilação da junção o suficiente para caber na memória, considere executar várias consultas que unam subconjuntos da tabela de compilação.

### Usar EXPLAIN para analisar consultas com junções complexas
<a name="performance-tuning-other-join-types"></a>

Consultas com condições de junção complexas (por exemplo, consultas que usam `LIKE`, `>` ou outros operadores) geralmente demandam muito computacionalmente. Na pior das hipóteses, cada registro de um lado da junção deve ser comparado a todos os registros do outro lado da junção. Como o tempo de execução aumenta com o quadrado do número de registros, as consultas correm o risco de exceder o tempo máximo de execução.

Para descobrir como o Athena executará sua consulta com antecedência, você pode usar a instrução `EXPLAIN`. Para obter mais informações, consulte [Usar EXPLAIN e EXPLAIN ANALYZE no Athena](athena-explain-statement.md) e [Noções básicas dos resultados da instrução EXPLAIN do Athena](athena-explain-statement-understanding.md).

## Reduzir o escopo das funções da janela ou removê-las
<a name="performance-tuning-optimizing-window-functions"></a>

Por serem operações que fazem uso intensivo de recursos, as funções de janela podem fazer com que as consultas sejam executadas lentamente ou até mesmo falhem com a mensagem Query exhausted resources at this scale factor. As funções de janela mantêm todos os registros em que operam na memória para calcular o resultado. Quando a janela é muito grande, a função de janela pode ficar sem memória.

Para garantir que suas consultas sejam executadas dentro dos limites de memória disponíveis, reduza o tamanho das janelas em que suas funções de janela operam. Para fazer isso, adicione uma cláusula `PARTITIONED BY` ou restrinja o escopo das cláusulas de particionamento existentes.

### Usar de funções que não são de janela
<a name="performance-tuning-optimizing-window-functions-rewrite"></a>

Às vezes, consultas com funções de janela podem ser gravadas sem funções de janela. Por exemplo, em vez de usar `row_number` para encontrar os principais registros `N`, você pode usar `ORDER BY` e `LIMIT`. Em vez de usar `row_number` ou `rank` para desduplicar registros, você pode usar funções agregadas como [max\$1by](https://trino.io/docs/current/functions/aggregate.html#max_by), [min\$1by](https://trino.io/docs/current/functions/aggregate.html#min_by) e [arbitrary](https://trino.io/docs/current/functions/aggregate.html#arbitrary).

Por exemplo, digamos que você tenha um conjunto de dados com atualizações de um sensor. O sensor informa periodicamente o status da bateria e inclui alguns metadados, como localização. Para saber o último status da bateria de cada sensor e sua localização, você pode usar esta consulta:

```
SELECT sensor_id,
       arbitrary(location) AS location,
       max_by(battery_status, updated_at) AS battery_status
FROM sensor_readings
GROUP BY sensor_id
```

Os metadados, como a localização, são os mesmos para cada registro, então você pode usar a função `arbitrary` para escolher qualquer valor do grupo. 

Para obter o último status da bateria, você pode usar a função `max_by`. A função `max_by` escolhe o valor de uma coluna do registro em que o valor máximo de outra coluna foi encontrado. Nesse caso, ela retorna o status da bateria do registro com a hora da última atualização dentro do grupo. Essa consulta é executada mais rapidamente e usa menos memória do que uma consulta equivalente com função de janela. 

## Otimizar agregações
<a name="performance-tuning-optimizing-aggregations"></a>

Ao realizar uma agregação, o Athena distribui os registros entre os nós de processamento usando as colunas na cláusula `GROUP BY`. Para tornar a tarefa de combinar registros com grupos o mais eficiente possível, os nós tentam manter os registros na memória, mas os vazam para o disco, se necessário.

Também é uma boa ideia evitar incluir colunas redundantes nas cláusulas `GROUP BY`. Como menos colunas exigem menos memória, uma consulta que usa menos colunas para descrever um grupo é mais eficiente. As colunas numéricas também usam menos memória do que as strings. Por exemplo, ao agregar um conjunto de dados que tenha um ID numérico de categoria e um nome de categoria, use somente a coluna ID da categoria na cláusula `GROUP BY`.

Às vezes, as consultas incluem colunas na cláusula `GROUP BY` para contornar o fato de que uma coluna deve ser parte da cláusula `GROUP BY` ou ser uma expressão agregada. Se essa regra não for seguida, você poderá receber uma mensagem de erro como esta:

 EXPRESSION\$1NOT\$1AGGREGATE: line 1:8: 'category' must be an aggregate expression or appear in GROUP BY clause 

Para evitar a necessidade de adicionar colunas redundantes à cláusula `GROUP BY`, use a função [arbitrary](https://trino.io/docs/current/functions/aggregate.html#arbitrary), como no exemplo a seguir.

```
SELECT country_id,
       arbitrary(country_name) AS country_name,
       COUNT(*) AS city_count
FROM world_cities
GROUP BY country_id
```

A função `ARBITRARY` retorna um valor de arbitrary do grupo. A função é útil quando você sabe que todos os registros do grupo têm o mesmo valor para uma coluna, mas o valor não identifica o grupo.

## Otimizar as principais N consultas
<a name="performance-tuning-optimizing-top-n-queries"></a>

A cláusula `ORDER BY` retorna os resultados de uma consulta em ordem de classificação. O Athena usa a classificação distribuída para executar a operação de classificação paralelamente em vários nós.

Se você não precisar estritamente que seu resultado seja classificado, evite adicionar uma cláusula `ORDER BY`. Além disso, evite adicionar `ORDER BY` a consultas internas se não for estritamente necessário. Em muitos casos, o planejador de consultas poderá remover a classificação redundante, mas isso não é garantido. Uma exceção a essa regra é se uma consulta interna estiver realizando uma operação principal `N`, como encontrar o `N` mais recente ou os valores de `N` mais comuns.

Quando o Athena vê `ORDER BY` junto com `LIMIT`, ele entende que você está executando uma consulta principal `N` e usa as operações dedicadas adequadamente.

**nota**  
Embora o Athena muitas vezes também possa detectar funções de janela como `row_number` que usa `N` principal, recomendamos a versão mais simples que usa `ORDER BY` e `LIMIT`. Para obter mais informações, consulte [Reduzir o escopo das funções da janela ou removê-las](#performance-tuning-optimizing-window-functions).

## Incluir somente as colunas obrigatórias
<a name="performance-tuning-include-only-required-columns"></a>

Caso não precise estritamente de uma coluna, não a inclua na consulta. Quanto menos dados a consulta precisar processar, mais rápido ela será executada. Isso reduz a quantidade de memória necessária e a quantidade de dados que devem ser enviados entre os nós. Se você estiver usando um formato de arquivo colunar, reduzir o número de colunas também reduzirá a quantidade de dados lidos do Amazon S3.

O Athena não tem limite específico para o número de colunas de um resultado, mas a forma como as consultas são executadas limita o possível tamanho combinado das colunas. O tamanho combinado das colunas inclui os nomes e tipos.

Por exemplo, o seguinte erro é causado por uma relação que excede o limite de tamanho de um descritor de relação:

 GENERIC\$1INTERNAL\$1ERROR: io.airlift.bytecode.CompilationException 

Para resolver esse problema, reduza o número de colunas na consulta ou crie subconsultas e use `JOIN` para recuperar uma quantidade menor de dados. Se você tiver consultas que executam `SELECT *` na consulta mais externa, altere `*` para uma lista com somente as colunas necessárias.

## Otimizar consultas com o uso de aproximações
<a name="performance-tuning-optimizing-queries-by-using-approximations"></a>

O Athena tem suporte para [funções agregadas de aproximação](https://trino.io/docs/current/functions/aggregate.html#appro) para contar valores distintos, valores mais frequentes, percentis (incluindo medianas aproximadas) e criar histogramas. Use essas funções sempre que não for necessário obter valores exatos.

Diferentemente das operações `COUNT(DISTINCT col)`, o [approx\$1distinct](https://trino.io/docs/current/functions/aggregate.html#approx_distinct) usa muito menos memória e é executado mais rápido. Da mesma forma, usar [numeric\$1histogram](https://trino.io/docs/current/functions/aggregate.html#numeric_histogram) em vez de [histogram](https://trino.io/docs/current/functions/aggregate.html#histogram) utiliza métodos aproximados e, portanto, menos memória.

## Otimizar LIKE
<a name="performance-tuning-optimizing-like"></a>

É possível usar `LIKE` para encontrar strings correspondentes, mas com strings longas, demanda uso intensivo de computação. Na maioria dos casos, a função [regexp\$1like](https://trino.io/docs/current/functions/regexp.html#regexp_like) é uma alternativa mais rápida e também oferece mais flexibilidade.

Muitas vezes, é possível otimizar uma pesquisa ancorando a substring que você está procurando. Por exemplo, se você estiver procurando por um prefixo, é muito melhor usar “*substr*%” em vez de “*substr*%”. Ou, se você estiver usando `regexp_like`, “^*substr*”.

## Usar UNION ALL em vez de UNION
<a name="performance-tuning-use-union-all-instead-of-union"></a>

 `UNION ALL` e `UNION` são duas maneiras de combinar os resultados de duas consultas em um único resultado. `UNION ALL` concatena os registros da primeira consulta com a segunda e `UNION` faz o mesmo, mas também remove as duplicatas. `UNION` precisa processar todos os registros e encontrar as duplicatas, o que requer uso intensivo de memória e computação, mas `UNION ALL` é uma operação relativamente rápida. A menos que você precise desduplicar registros, use `UNION ALL` para obter a melhor performance.

## Usar UNLOAD para grandes conjuntos de resultados
<a name="performance-tuning-use-unload-for-large-result-sets"></a>

Quando se espera que os resultados da consulta sejam grandes (por exemplo, dezenas de milhares de linhas ou mais), use UNLOAD para exportar os resultados. Na maioria dos casos, isso é mais rápido do que executar uma consulta normal, e usar `UNLOAD` também oferece mais controle sobre a saída.

Quando a consulta acaba de ser executada, o Athena armazena o resultado como um único arquivo CSV não compactado no Amazon S3. Isso leva mais tempo que usar `UNLOAD`, não apenas porque o resultado não está compactado, mas também porque a operação não pode ser paralelizada. Por sua vez, `UNLOAD` grava os resultados diretamente dos nós de trabalho e faz uso total do paralelismo do cluster de computação. Além disso, é possível configurar `UNLOAD` para gravar os resultados em formato compactado e em outros formatos de arquivo, como JSON e Parquet.

Para obter mais informações, consulte [UNLOAD](unload.md). 

## Use CTAS ou o Glue ETL para materializar agregações usadas com frequência
<a name="performance-tuning-use-ctas-or-glue-etl-to-materialize-frequently-used-aggregations"></a>

“Materializar” uma consulta é uma forma de acelerar a performance da consulta armazenando resultados de consultas complexas pré-computados (por exemplo, agregações e junções) para reutilização em consultas subsequentes.

Se muitas de suas consultas incluírem as mesmas junções e agregações, você poderá materializar a subconsulta comum como uma nova tabela e executar consultas nessa tabela. É possível criar a nova tabela com [Criar uma tabela com base em resultados de consultas (CTAS)](ctas.md) ou com uma ferramenta ETL dedicada, como o [Glue ETL](https://aws.amazon.com/glue).

Por exemplo, digamos que você tenha um painel com widgets que exibem diferentes aspectos de um conjunto de dados de pedidos. Cada widget tem sua própria consulta, mas todas as consultas compartilham as mesmas junções e filtros. Uma tabela de pedidos é unida a uma tabela de itens de linha, e há um filtro para exibir somente os últimos três meses. Se você identificar os atributos comuns dessas consultas, poderá criar uma nova tabela que os widgets possam usar. Isso reduz a duplicação e melhora a performance. A desvantagem é que você deverá manter a nova tabela atualizada.

## Reutilizar resultados da consulta
<a name="performance-tuning-reuse-query-results"></a>

É comum que a mesma consulta seja executada várias vezes em pouco tempo. Por exemplo, isso pode ocorrer quando várias pessoas abrem o mesmo painel de dados. Ao executar uma consulta, você pode pedir para o Athena reutilizar os resultados calculados anteriormente. Especifique a idade máxima dos resultados a serem reutilizados. Se a mesma consulta for executada anteriormente dentro desse período, o Athena retornará esses resultados em vez de executar a consulta novamente. Para obter mais informações, consulte [Reutilização de resultados da consulta no Athena](reusing-query-results.md) aqui no *Guia do usuário do Amazon Athena* e [Reduce cost and improve query performance with Amazon Athena Query Result Reuse](https://aws.amazon.com/blogs/big-data/reduce-cost-and-improve-query-performance-with-amazon-athena-query-result-reuse/) no *blog de big data da AWS*.

# Otimizar dados
<a name="performance-tuning-data-optimization-techniques"></a>

A performance não depende apenas das consultas, mas também, principalmente, de como seu conjunto de dados está organizado e do formato de arquivo e da compactação que ele usa.

## Particionar dados
<a name="performance-tuning-partition-your-data"></a>

O particionamento divide a tabela em partes e mantém os dados relacionados juntos com base em propriedades como data, país ou região. As chaves de partição atuam como colunas virtuais. Você define as chaves de partição na criação da tabela e as utiliza para filtrar consultas. Quando você filtra as colunas das chaves de partição, somente os dados das partições correspondentes são lidos. Por exemplo, se o conjunto de dados estiver particionado por data e a consulta tiver um filtro que corresponda somente à última semana, somente os dados da última semana serão lidos. Para obter mais informações sobre particionamento, consulte [Particionar dados](partitions.md).

## Escolher chaves de partição que oferecerão suporte às suas consultas
<a name="performance-tuning-pick-partition-keys-that-will-support-your-queries"></a>

Como o particionamento tem um impacto significativo na performance da consulta, pense com atenção em como você particionará ao criar seu conjunto de dados e tabelas. Ter muitas chaves de partição pode resultar em conjuntos de dados fragmentados com excesso de arquivos e arquivos muito pequenos. Por outro lado, ter poucas chaves de partição ou não ter particionamento leva a consultas que examinam mais dados do que o necessário.

### Evitar otimização de consultas raras
<a name="performance-tuning-avoid-optimizing-for-rare-queries"></a>

Uma boa estratégia é otimizar as consultas mais comuns e evitar a otimização de consultas raras. Por exemplo, se as consultas analisarem períodos de dias, não particione por hora, mesmo que algumas consultas sejam filtradas até esse nível. Se seus dados tiverem uma coluna de timestamp granular, as consultas raras que filtram por hora poderão usar a coluna de timestamp. Mesmo que casos raros verifiquem um pouco mais de dados do que o necessário, reduzir a performance geral em prol de casos raros geralmente não é vantajoso.

Para reduzir a quantidade de dados que as consultas precisam verificar e, assim, melhorar a performance, use um formato de arquivo colunar e mantenha os registros ordenados. Em vez de particionar por hora, mantenha os registros classificados por carimbo de data e hora. Para consultas em janelas de tempo mais curtas, a classificação por carimbo de data e hora é quase tão eficiente quanto a partição por hora. Além disso, a classificação por carimbo de data e hora normalmente não prejudica a performance das consultas nas janelas de tempo contadas em dias. Para obter mais informações, consulte [Usar formatos de arquivo colunares](#performance-tuning-use-columnar-file-formats).

As consultas em tabelas com dezenas de milhares de partições terão melhor performance se houver predicados em todas as chaves de partição. Esse é outro motivo para criar um esquema de particionamento para as consultas mais comuns. Para obter mais informações, consulte [Consultar partições por igualdade](#performance-tuning-query-partitions-by-equality).

## Usar projeção de partições
<a name="performance-tuning-use-partition-projection"></a>

A projeção de partição é um atributo do Athena que armazena informações de partição não no AWS Glue Data Catalog, mas como regras nas propriedades da tabela no AWS Glue. Ao planejar uma consulta em uma tabela configurada com projeção de partição, o Athena lê as regras de projeção de partição da tabela. O Athena calcula as partições a serem lidas na memória com base na consulta e nas regras, em vez de procurar partições no AWS Glue Data Catalog.

Além de simplificar o gerenciamento de partições, a projeção de partições pode melhorar a performance de conjuntos de dados que têm um grande número de partições. Quando a consulta contém intervalos em vez de valores específicos para chaves de partição, a busca por partições correspondentes no catálogo demora mais quanto mais partições houver. Com a projeção de partição, o filtro pode ser computado na memória sem acessar o catálogo e pode ser muito mais rápido.

Em determinadas circunstâncias, a projeção de partições pode resultar em pior performance. Um exemplo ocorre quando uma tabela é “avulsa”. Uma tabela avulsa não tem dados para cada permutação dos valores da chave de partição descritos pela configuração da projeção da partição. Com uma tabela avulsa, o conjunto de partições calculado com base na consulta e a configuração da projeção da partição são listados no Amazon S3, mesmo quando não contêm dados.

Ao usar a projeção de partição, verifique se incluiu predicados em todas as chaves de partição. Limite o escopo dos valores possíveis para evitar listas desnecessárias do Amazon S3. Imagine uma chave de partição que contenha um intervalo de um milhão de valores e uma consulta que não tenha nenhum filtro nessa chave de partição. Para executar a consulta, o Athena deverá realizar pelo menos um milhão de operações de lista do Amazon S3. As consultas são mais rápidas quando você consulta valores específicos, independentemente de usar a projeção de partição ou armazenar informações de partição no catálogo. Para obter mais informações, consulte [Consultar partições por igualdade](#performance-tuning-query-partitions-by-equality).

Ao configurar uma tabela para projeção de partições, verifique se os intervalos especificados são razoáveis. Se a consulta não incluir um predicado em uma chave de partição, todos os valores no intervalo dessa chave serão usados. Se o conjunto de dados foi criado em uma data específica, use essa data como ponto de partida para qualquer intervalo de datas. Use `NOW` como fim de intervalos de datas. Evite intervalos numéricos que tenham um grande número de valores e considere usar o tipo [injected](partition-projection-dynamic-id-partitioning.md#partition-projection-injection) em vez disso.

Para obter mais informações sobre projeção de partições, consulte [Usar projeção de partições com o Amazon Athena](partition-projection.md).

## Usar índices de partição
<a name="performance-tuning-use-partition-indexes"></a>

Os índices de partição são um atributo do AWS Glue Data Catalog que melhoram a performance da pesquisa de partições para tabelas que têm um grande número de partições.

A lista de partições do catálogo é como uma tabela em um banco de dados relacional. A tabela contém colunas para as chaves de partição e uma coluna adicional para o local da partição. Quando você consulta uma tabela particionada, os locais das partições são pesquisados por meio da verificação dessa tabela.

Assim como nos bancos de dados relacionais, é possível aumentar a performance das consultas adicionando índices. É possível adicionar vários índices para oferecer suporte a diferentes padrões de consulta. O índice de partição do AWS Glue Data Catalog é compatível com operadores de igualdade e comparação, como `>`, `>=` e `<` combinados com o operador `AND`. Para obter mais informações, consulte [Working with partition indexes in AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html) no *Guia do desenvolvedor do AWS Glue* e [Improve Amazon Athena query performance using AWS Glue Data Catalog partition indexes](https://aws.amazon.com/blogs/big-data/improve-amazon-athena-query-performance-using-aws-glue-data-catalog-partition-indexes/) no *blog de big data da AWS*.

## Use sempre STRING como o tipo para chaves de partição
<a name="performance-tuning-always-use-string-as-the-type-for-partition-keys"></a>

Ao consultar chaves de partição, lembre-se de que o Athena exige que as chaves de partição sejam do tipo `STRING` para inserir a filtragem de partição no AWS Glue. Se o número de partições não for pequeno, usar outros tipos poderá reduzir a performance. Se os valores da chave de partição forem semelhantes a uma data ou a um número, converta-os ao tipo apropriado em sua consulta.

## Remover partições antigas e vazias
<a name="performance-tuning-remove-old-and-empty-partitions"></a>

Se você remover dados de uma partição no Amazon S3 (por exemplo, usando o [ciclo de vida](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) do Amazon S3), também deverá remover a entrada da partição do AWS Glue Data Catalog. Durante o planejamento da consulta, toda partição correspondente à consulta é listada no Amazon S3. Se houver muitas partições vazias, a sobrecarga de listar essas partições poderá ser prejudicial.

Além disso, se houver milhares de partições, considere remover os metadados da partição de dados antigos que não são mais relevantes. Por exemplo, se as consultas nunca buscarem dados com mais de um ano, você poderá remover periodicamente os metadados das partições mais antigas. Se o número de partições aumentar para dezenas de milhares, remover partições não utilizadas pode acelerar as consultas que não incluem predicados em todas as chaves de partição. Para obter informações sobre como incluir predicados em todas as chaves de partição de suas consultas, consulte [Consultar partições por igualdade](#performance-tuning-query-partitions-by-equality).

## Consultar partições por igualdade
<a name="performance-tuning-query-partitions-by-equality"></a>

As consultas que contêm predicados de igualdade em todas as chaves de partição são executadas mais rapidamente porque os metadados da partição podem ser carregados diretamente. Evite consultas nas quais uma ou mais chaves de partição não tenham um predicado, ou o predicado seleciona uma faixa de valores. Para essas consultas, a lista de todas as partições deverá ser filtrada para encontrar valores correspondentes. Para a maioria das tabelas, a sobrecarga é mínima, mas para tabelas com dezenas de milhares de partições ou mais, a sobrecarga pode ser considerável.

Se não for possível gravar novamente suas consultas para filtrar partições por igualdade, você pode tentar a projeção de partições. Para obter mais informações, consulte [Usar projeção de partições](#performance-tuning-use-partition-projection).

## Evitar usar MSCK REPAIR TABLE para manutenção de partições
<a name="performance-tuning-avoid-using-msck-repair-table-for-partition-maintenance"></a>

Como `MSCK REPAIR TABLE` pode levar muito tempo para ser executado, apenas adiciona novas partições e não remove partições antigas, não é uma forma eficiente de gerenciar partições (consulte [Considerações e limitações](msck-repair-table.md#msck-repair-table-considerations)).

É melhor gerenciar partições manualmente usando as [APIs do AWS Glue Data Catalog](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-catalog.html), [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) ou [crawlers do AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/crawler-running.html). Se preferir, você pode usar a projeção de partições, que elimina totalmente a necessidade de gerenciar as partições. Para obter mais informações, consulte [Usar projeção de partições com o Amazon Athena](partition-projection.md).

## Verifique se suas consultas são compatíveis com o esquema de particionamento
<a name="performance-tuning-validate-that-your-queries-are-compatible-with-the-partitioning-scheme"></a>

É possível verificar com antecedência quais partições uma consulta examinará usando a instrução [`EXPLAIN`](athena-explain-statement.md). Prefixe sua consulta com a palavra-chave `EXPLAIN` e procure o fragmento de origem (por exemplo `Fragment 2 [SOURCE]`) para cada tabela na parte inferior da saída de `EXPLAIN`. Procure atribuições em que o lado direito esteja definido como chave de partição. A linha abaixo contém uma lista de todos os valores dessa chave de partição que serão verificados quando a consulta for executada.

Por exemplo, digamos que você tenha uma consulta em uma tabela com uma chave de partição `dt` e prefixe a consulta com `EXPLAIN`. Se os valores da consulta forem datas e um filtro selecionar um intervalo de três dias, a saída de `EXPLAIN` poderá ser mais ou menos assim:

```
dt := dt:string:PARTITION_KEY
    :: [[2023-06-11], [2023-06-12], [2023-06-13]]
```

A saída de `EXPLAIN` mostra que o planejador encontrou três valores para essa chave de partição que corresponderam à consulta. Ela também mostra quais são esses valores. Para obter mais informações sobre o uso de `EXPLAIN`, consulte [Usar EXPLAIN e EXPLAIN ANALYZE no Athena](athena-explain-statement.md) e [Noções básicas dos resultados da instrução EXPLAIN do Athena](athena-explain-statement-understanding.md).

## Usar formatos de arquivo colunares
<a name="performance-tuning-use-columnar-file-formats"></a>

Formatos de arquivo colunar, como Parquet e ORC, foram criados para workloads de analytics distribuídas. Eles organizam os dados por coluna, não por linha. Organizar os dados em formato colunar oferece as seguintes vantagens:
+ Apenas as colunas necessárias para a consulta são carregadas
+ Reduz-se a quantidade geral de dados que precisam ser carregados
+ Os valores das colunas são armazenados juntos, de modo que os dados possam ser compactados com eficiência 
+ Os arquivos podem conter metadados que permitam que o mecanismo ignore o carregamento de dados desnecessários

Como exemplo de como podemos usar os metadados do arquivo, os metadados do arquivo podem conter informações sobre os valores mínimo e máximo em uma página de dados. Se os valores consultados não estiverem no intervalo indicado nos metadados, a página poderá ser ignorada.

Uma forma de usar esses metadados para melhorar a performance é garantir que os dados dos arquivos sejam classificados. Por exemplo, digamos que você tenha consultas que buscam registros em que a entrada `created_at` esteja em um curto espaço de tempo. Se seus dados forem classificados pela coluna `created_at`, o Athena poderá usar os valores mínimo e máximo dos metadados do arquivo para ignorar as partes desnecessárias dos arquivos de dados.

Ao usar formatos de arquivo colunar, verifique se seus arquivos não são pequenos demais. Conforme observado em [Evite ter uma quantidade muito grande de arquivos](#performance-tuning-avoid-having-too-many-files), conjuntos de dados com muitos arquivos pequenos causam problemas de performance. Isso ocorre especialmente com formatos de arquivo colunar. Em arquivos pequenos, a sobrecarga do formato de arquivo colunar supera os benefícios.

O Parquet e o ORC são organizados internamente por grupos de linhas (Parquet) e faixas (ORC). O tamanho padrão para grupos de linhas é 128 MB, e para faixas, 64 MB. Se houver muitas colunas, você poderá aumentar o grupo de linhas e o tamanho da faixa para melhorar a performance. Não é recomendável diminuir o tamanho do grupo de linhas ou da faixa para um valor inferior ao padrão.

Para converter outros formatos de dados em Parquet ou ORC, você pode usar o AWS Glue ETL ou o Athena. Para obter mais informações, consulte [Converter em formatos colunares](columnar-storage.md#convert-to-columnar).

## Compactar dados
<a name="performance-tuning-compress-data"></a>

O Athena é compatível com uma ampla variedade de formatos de compactação. Consultar dados compactados é mais rápido e mais barato, pois você paga pelo número de bytes verificados antes da descompactação.

O formato [gzip](https://www.gnu.org/software/gzip/) fornece boas taxas de compactação e oferece amplo suporte a outras ferramentas e serviços. O formato [zstd](https://facebook.github.io/zstd/) (Zstandard) é um formato de compactação mais recente com um bom equilíbrio entre performance e taxa de compactação.

Ao compactar arquivos de texto, como dados JSON e CSV, tente chegar a um equilíbrio entre o número de arquivos e o tamanho dos arquivos. A maioria dos formatos de compactação exige que o leitor leia os arquivos desde o início. Isso significa que, em geral, os arquivos de texto compactados não podem ser processados em paralelo. Arquivos grandes não compactados muitas vezes são divididos entre operadores para obter maior paralelismo durante o processamento da consulta, mas isso não é possível com a maioria dos formatos de compactação.

Conforme discutido em [Evite ter uma quantidade muito grande de arquivos](#performance-tuning-avoid-having-too-many-files), é melhor não ter uma quantidade muito grande nem muito pequena de arquivos. Como o número de arquivos é o limite de quantos operadores podem processar a consulta, essa regra se aplica principalmente a arquivos compactados.

Para obter mais informações sobre uso de compactação no Athena, consulte [Usar compactação no Athena](compression-formats.md).

## Usar bucketing para pesquisas em chaves com alta cardinalidade
<a name="performance-tuning-use-bucketing-for-lookups-on-keys-with-high-cardinality"></a>

O bucketing é uma técnica para distribuir registros em arquivos separados com base no valor de uma das colunas. Isso garante que todos os registros com o mesmo valor estejam no mesmo arquivo. O bucketing é útil quando você tem uma chave com alta cardinalidade e muitas de suas consultas buscam valores específicos da chave.

Por exemplo, digamos que você consulte um conjunto de registros de um usuário específico. Se os dados forem agrupados em bucket por ID de usuário, o Athena saberá com antecedência quais arquivos contêm registros para um ID específico e quais não. Isso permite que o Athena leia somente os arquivos que possam conter o ID, reduzindo consideravelmente a quantidade de dados lidos. Também reduz o tempo de computação que, de outra forma, seria necessário para pesquisar os dados em busca do ID específico.

### Como evitar bucketing quando as consultas frequentemente pesquisam vários valores em uma coluna
<a name="performance-tuning-disadvantages-of-bucketing"></a>

O bucketing é menos vantajoso quando as consultas frequentemente pesquisam vários valores na coluna pela qual os dados são agrupados em bucket. Quanto mais valores forem consultados, maior será a probabilidade de que seja necessário ler todos ou a maioria dos arquivos. Por exemplo, se você tiver três buckets e uma consulta procurar três valores diferentes, talvez seja necessário ler todos os arquivos. O bucketing funciona melhor quando as consultas pesquisam valores únicos.

Para obter mais informações, consulte [Usar particionamento e bucketing](ctas-partitioning-and-bucketing.md).

## Evite ter uma quantidade muito grande de arquivos
<a name="performance-tuning-avoid-having-too-many-files"></a>

Conjuntos de dados que consistem em muitos arquivos pequenos resultam em baixo desempenho geral da consulta. Ao planejar uma consulta, o Athena lista todos os locais das partições, o que leva tempo. O tratamento e a solicitação de cada arquivo também geram uma sobrecarga computacional. Portanto, é mais rápido carregar um único arquivo maior do Amazon S3 do que carregar os mesmos registros de muitos arquivos menores.

Em casos extremos, é possível encontrar limites de serviço do Amazon S3. O Amazon S3 é compatível com até 5.500 solicitações por segundo para uma única partição de índice. Inicialmente, o bucket é tratado como uma única partição de índice, mas à medida que as cargas de solicitações aumentam, ele pode ser dividido em várias partições de índice.

O Amazon S3 analisa os padrões de solicitação e as divisões com base nos prefixos de chave. Se seu conjunto de dados consistir em muitos milhares de arquivos, as solicitações provenientes do Athena poderão exceder a cota de solicitações. Mesmo com menos arquivos, a cota poderá ser excedida se forem feitas várias consultas simultâneas no mesmo conjunto de dados. Outras aplicações que acessam os mesmos arquivos podem contribuir para o número total de solicitações.

Quando o `limit` da taxa de solicitação é excedido, o Amazon S3 retorna o erro a seguir. Esse erro está incluído nas informações de status da consulta no Athena.

 SlowDown: Please reduce your request rate 

Para solucionar problemas, comece determinando se o erro foi causado por uma única consulta ou por várias consultas que leem os mesmos arquivos. No último caso, coordene a execução das consultas de modo que não sejam executadas ao mesmo tempo. Para obter isso, adicione um mecanismo de enfileiramento ou até mesmo novas tentativas em sua aplicação.

Se a execução de uma única consulta acionar o erro, tente combinar arquivos de dados ou modificar a consulta para ler menos arquivos. O melhor momento para combinar arquivos pequenos é antes de serem gravados. Para isso, considere as seguintes técnicas:
+ Altere o processo que grava arquivos para gravar arquivos maiores. Por exemplo, é possível armazenar registros em buffer por mais tempo antes de serem gravados. 
+ Coloque arquivos em um local do Amazon S3 e use uma ferramenta como o Glue ETL para combiná-los em arquivos maiores. Em seguida, mova os arquivos maiores para o local ao qual a tabela aponta. Para obter mais informações, consulte [Reading input files in larger groups](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html) no *Guia do desenvolvedor do AWS Glue* ou [How can I configure an AWS Glue ETL job to output larger files?](https://repost.aws/knowledge-center/glue-job-output-large-files) no *Centro de Conhecimento AWS re:Post*.
+ Reduza o número de chaves de partição. Quando há muitas chaves de partição, cada partição pode ter poucos registros, resultando em um número excessivo de arquivos pequenos. Para obter informações sobre como decidir quais partições criar, consulte [Escolher chaves de partição que oferecerão suporte às suas consultas](#performance-tuning-pick-partition-keys-that-will-support-your-queries).

## Evitar hierarquias de armazenamento adicionais além da partição
<a name="performance-tuning-avoid-additional-storage-hierarchies-beyond-the-partition"></a>

Para evitar a sobrecarga do planejamento de consultas, armazene os arquivos em uma estrutura plana em cada local da partição. Não use hierarquias de diretório adicionais.

Ao planejar uma consulta, o Athena lista todos os arquivos em todas as partições correspondentes à consulta. Embora o Amazon S3 não tenha diretórios em si, a convenção é interpretar a barra direta `/` como separador de diretório. Ao listar os locais das partições, o Athena lista recursivamente qualquer diretório que encontrar. Quando os arquivos de uma partição são organizados em hierarquia, ocorrem várias rodadas de listagens.

Quando todos os arquivos estão diretamente no local da partição, na maioria das vezes, apenas uma operação de lista precisa ser executada. Porém, várias operações de lista sequencial serão necessárias se você tiver mais de mil arquivos em uma partição porque o Amazon S3 retorna somente mil objetos por operação de lista. Ter mais de mil arquivos em uma partição também pode criar outros problemas de performance mais graves. Para obter mais informações, consulte [Evite ter uma quantidade muito grande de arquivos](#performance-tuning-avoid-having-too-many-files). 

## Use SymlinkTextInputFormat somente quando necessário
<a name="performance-tuning-use-symlinktextinputformat-only-when-necessary"></a>

Usar a técnica [https://athena.guide/articles/stitching-tables-with-symlinktextinputformat](https://athena.guide/articles/stitching-tables-with-symlinktextinputformat) pode ser uma forma de resolver situações em que os arquivos da tabela não estão bem organizados em partições. Por exemplo, links simbólicos podem ser úteis quando todos os arquivos estão no mesmo prefixo ou quando há arquivos com esquemas diferentes no mesmo local.

Porém, usar links simbólicos adiciona níveis de indireção à execução da consulta. Esses níveis de indireção afetam a performance geral. Os arquivos de links simbólicos precisam ser lidos, e os locais que eles definem devem ser listados. Isso adiciona muitas viagens de ida e volta ao Amazon S3 que as tabelas habituais do Hive não exigem. Concluindo, você deverá usar `SymlinkTextInputFormat` somente quando não houver opções melhores disponíveis, como reorganizar arquivos.

# Usar formatos de armazenamento colunares
<a name="columnar-storage"></a>

[Apache Parquet](https://parquet.apache.org) e [ORC](https://orc.apache.org/) são formatos de armazenamento colunar otimizados para recuperação rápida de dados usados em aplicações de análises da AWS.

Os formatos de armazenamento colunar têm as seguintes características que os tornam adequados para o uso com o Athena: 
+ *Compactação por coluna, com algoritmo de compactação selecionado para o tipo de dados da coluna* para economizar espaço de armazenamento no Amazon S3 e reduzir E/S e espaço no disco durante o processamento de consultas.
+ A *aplicação de predicados* em Parquet e ORC permite que as consultas do Athena busquem somente os blocos de que precisa, melhorando a performance das consultas. Quando uma consulta do Athena obtém valores de coluna específicos dos seus dados, ela usa as estatísticas dos predicados de bloco de dados, como valores máximos e mínimos, para determinar se é para ler ou ignorar o bloco. 
+ A *divisão de dados* em Parquet e ORC permite que o Athena divida a leitura de dados entre vários leitores e aumente o paralelismo durante o processamento da consulta. 

Para converter seus dados brutos existentes de outros formatos de armazenamento em Parquet ou ORC, é possível executar consultas [CREATE TABLE AS SELECT (CTAS)](ctas.md) no Athena e especificar um formato de armazenamento de dados como Parquet ou ORC, ou usar o crawler do AWS Glue.

## Escolher entre Parquet e ORC
<a name="columnar-storage-choosing"></a>

A escolha entre ORC (Optimized Row Columnar) e Parquet depende de seus requisitos específicos de uso.

O Apache Parquet fornece esquemas eficientes de compactação e codificação de dados e é ideal para executar consultas complexas e processar grandes quantidades de dados. O Parquet é otimizado para uso com o [Apache Arrow](https://arrow.apache.org/), o que pode ser vantajoso se você usar ferramentas relacionadas ao Arrow.

O ORC fornece uma maneira eficiente de armazenar dados do Hive. Os arquivos ORC geralmente são menores do que os arquivos Parquet, e os índices ORC podem agilizar as consultas. Além disso, o ORC é compatível com tipos complexos, como estruturas, mapas e listas.

Ao escolher entre Parquet e ORC, considere o seguinte:

**Desempenho da consulta**: o Parquet é compatível com uma variedade maior de tipos de consulta, por isso pode ser a melhor opção se você planeja realizar consultas complexas. 

**Tipos de dados complexos**: se você estiver usando tipos de dados complexos, o ORC pode ser a melhor opção, porque ele é compatível com uma variedade maior de tipos de dados complexos.

**Tamanho do arquivo**: se o espaço em disco for uma preocupação, o ORC geralmente resulta em arquivos menores, o que pode reduzir os custos de armazenamento.

**Compactação**: tanto o Parquet quanto o ORC oferecem boa compactação, mas o melhor formato para você pode depender do seu caso específico de uso.

**Evolução**: tanto o Parquet quanto o ORC são compatíveis com uma evolução do esquema, o que significa que você pode adicionar, remover ou modificar colunas ao longo do tempo.

Tanto o Parquet quanto o ORC são boas opções para aplicações de big data, mas considere os requisitos do seu cenário antes de escolher. Talvez você queira realizar avaliações comparativas em seus dados e consultas para ver qual formato funciona melhor para seu caso de uso.

## Converter em formatos colunares
<a name="convert-to-columnar"></a>

As opções para converter facilmente dados de origem, como JSON ou CSV, em um formato colunar, incluem o uso de consultas [CREATE TABLE AS](ctas.md) ou a execução de trabalhos no AWS Glue.
+ Você pode usar consultas (CTAS) `CREATE TABLE AS` para converter dados em Parquet ou ORC em uma única etapa. Para ver um exemplo, consulte [Exemplo: gravar resultados da consulta em um formato diferente](https://docs.aws.amazon.com/athena/latest/ug/ctas-examples.html#ctas-example-format) na página [Exemplos de consultas CTAS](ctas-examples.md).
+ Para obter informações sobre como usar o Athena para ETL para transformar dados de CSV em Parquet, consulte [Usar CTAS e INSERT INTO para ETL e análise de dados](ctas-insert-into-etl.md).
+ Para obter informações sobre como executar um trabalho do AWS Glue para transformar dados CSV em Parquet, consulte a seção “Transformar dados CSV em formato Parquet” na publicação [Construir a fundação de um data lake com o AWS Glue e o Amazon S3](https://aws.amazon.com/blogs/big-data/build-a-data-lake-foundation-with-aws-glue-and-amazon-s3/) no blog sobre big data da AWS. O AWS Glue oferece suporte à mesma técnica para converter dados CSV em ORC ou dados JSON em Parquet ou ORC.

# Usar particionamento e bucketing
<a name="ctas-partitioning-and-bucketing"></a>

O particionamento e o bucketing são duas formas de reduzir a quantidade de dados que o Athena deve verificar quando você executa uma consulta. O particionamento e o bucketing são complementares e podem ser usados em conjunto. Reduzir a quantidade de dados verificados gera uma performance melhor a um custo menor. Para obter diretrizes gerais sobre a performance das consultas do Athena, consulte [As dez melhores dicas de ajuste de performance para o Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/).

**Topics**
+ [

# O que é particionamento?
](ctas-partitioning-and-bucketing-what-is-partitioning.md)
+ [

# O que é bucketing?
](ctas-partitioning-and-bucketing-what-is-bucketing.md)
+ [

# Recursos adicionais
](ctas-partitioning-and-bucketing-additional-resources.md)

# O que é particionamento?
<a name="ctas-partitioning-and-bucketing-what-is-partitioning"></a>

Particionamento significa organizar dados em diretórios (ou “prefixos”) no Amazon S3 com base em uma propriedade específica dos dados. Essas propriedades são chamadas chaves de partição. Uma chave de partição comum é a data ou alguma outra unidade de tempo, como ano ou mês. Porém, um conjunto de dados pode ser particionado por mais de uma chave. Por exemplo, dados sobre vendas de produtos podem ser divididos por data, categoria do produto e mercado.

## Decidir como particionar
<a name="ctas-partitioning-and-bucketing-deciding-how-to-partition"></a>

Bons candidatos para chaves de partição são as propriedades que sempre ou quase sempre são usadas em consultas e têm baixa cardinalidade. Há um equilíbrio entre ter partições em excesso e não ter partições suficientes. Com partições em excesso, o aumento do número de arquivos cria sobrecarga. Também há sobrecarga na filtragem das partições em si. Com poucas partições, as consultas geralmente precisam verificar mais dados.

## Criar uma tabela particionada
<a name="ctas-partitioning-and-bucketing-creating-a-partitioned-table"></a>

Quando um conjunto de dados é particionado, é possível criar uma tabela particionada no Athena. Uma tabela particionada é uma tabela que contém chaves de partição. Ao usar `CREATE TABLE`, você adiciona partições à tabela. Quando você usa `CREATE TABLE AS`, as partições criadas no Amazon S3 são adicionadas automaticamente à tabela.

Em uma instrução `CREATE TABLE`, você especifica as chaves de partição na cláusula `PARTITIONED BY (column_name data_type)`. Em uma instrução `CREATE TABLE AS`, você especifica as chaves de partição em uma cláusula `WITH (partitioned_by = ARRAY['partition_key'])` ou `WITH (partitioning = ARRAY['partition_key'])` para tabelas Iceberg. Por questões de performance, as chaves de partição devem ser sempre do tipo `STRING`. Para obter mais informações, consulte [Usar string como o tipo de dados para chaves de partição](data-types-timestamps.md#data-types-timestamps-partition-key-types).

Para obter mais detalhes de sintaxe de `CREATE TABLE` e `CREATE TABLE AS`, consulte [CREATE TABLE](create-table.md) e [Propriedades da tabela CTAS](create-table-as.md#ctas-table-properties).

## Consultar tabelas particionadas
<a name="ctas-partitioning-and-bucketing-querying-partitioned-tables"></a>

Quando você consulta uma tabela particionada, o Athena usa os predicados da consulta para filtrar a lista de partições. Em seguida, ele utiliza os locais das partições correspondentes para processar os arquivos encontrados. O Athena pode reduzir com eficiência a quantidade de dados verificados simplesmente não lendo dados nas partições que não correspondam aos predicados da consulta.

### Exemplos
<a name="ctas-partitioning-and-bucketing-partitioned-table-example-queries"></a>

Suponha que você tenha uma tabela particionada por `sales_date` e `product_category` e queira saber a receita total de uma semana em uma categoria específica. Inclua predicados nas colunas`sales_date` e `product_category` para garantir que o Athena verificará somente a quantidade mínima de dados, como no exemplo a seguir.

```
SELECT SUM(amount) AS total_revenue 
FROM sales 
WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' 
AND product_category = 'Toys'
```

Suponha que você tenha um conjunto de dados que seja particionado por data, mas também tenha um carimbo de data e hora refinado.

Com as tabelas Iceberg, é possível declarar que uma chave de partição tem uma relação com uma coluna, mas com as tabelas Hive, o mecanismo de consulta não tem conhecimento das relações entre colunas e chaves de partição. Por esse motivo, é necessário incluir um predicado na coluna e na chave de partição da consulta para garantir que a consulta não verifique mais dados do que o necessário.

Por exemplo, suponha que a tabela `sales` no exemplo anterior também tenha uma coluna `sold_at` do tipo de dados `TIMESTAMP`. Se você quiser somente a receita de um intervalo de tempo específico, escreva a consulta da seguinte forma:

```
SELECT SUM(amount) AS total_revenue 
FROM sales 
WHERE sales_date = '2023-02-28' 
AND sold_at BETWEEN TIMESTAMP '2023-02-28 10:00:00' AND TIMESTAMP '2023-02-28 12:00:00' 
AND product_category = 'Toys'
```

Para obter mais informações sobre a diferença entre consultar tabelas Hive e Iceberg, consulte [Como gravar consultas em campos de timestamp que também são particionados por tempo](data-types-timestamps.md#data-types-timestamps-how-to-write-queries-for-timestamp-fields-that-are-also-time-partitioned).

# O que é bucketing?
<a name="ctas-partitioning-and-bucketing-what-is-bucketing"></a>

Bucketing é uma forma de organizar os registros de um conjunto de dados em categorias chamadas buckets.

Esse significado de bucket e bucketing é diferente dos buckets do Amazon S3 e não devem ser confundidos. No bucketing de dados, os registros que têm o mesmo valor para uma propriedade vão para o mesmo bucket. Os registros são distribuídos da forma mais uniforme possível entre os buckets, de modo que cada bucket tenha aproximadamente a mesma quantidade de dados.

Na prática, os buckets são arquivos, e uma função de hash determina o bucket em que um registro entrará. Um conjunto de dados em bucket terá um ou mais arquivos por bucket por partição. O bucket ao qual um arquivo pertence está codificado no nome do arquivo.

## Benefícios do bucketing
<a name="ctas-partitioning-and-bucketing-bucketing-benefits"></a>

O bucketing é útil quando um conjunto de dados é classificado em bucket por determinada propriedade, e convém recuperar registros nos quais essa propriedade tenha determinado valor. Como os dados estão em buckets, o Athena pode usar o valor para determinar quais arquivos examinar. Por exemplo, suponha que um conjunto de dados esteja em buckets `customer_id` e você queira localizar todos os registros de um cliente específico. O Athena determina o bucket que contém os registros e lê somente os arquivos desse bucket.

Bons candidatos para bucketing ocorrem quando há colunas que têm alta cardinalidade (ou seja, com muitos valores distintos), estão uniformemente distribuídas e que você frequentemente consulta buscando valores específicos.

**nota**  
O Athena não é compatível com o uso de `INSERT INTO` para adicionar novos registros a tabelas em bucket.

## Tipos de dados compatíveis com a filtragem em colunas em bucket
<a name="ctas-partitioning-and-bucketing-data-types-supported-for-filtering-on-bucketed-columns"></a>

É possível adicionar filtros em colunas classificadas por buckets com determinados tipos de dados. O Athena permite essa filtragem nas colunas em bucket com os seguintes tipos de dados:
+ BOOLEAN
+ BYTE
+ DATE
+ DOUBLE
+ FLOAT
+ INT
+ LONG
+ SHORT
+ STRING
+ VARCHAR

## Compatível com Hive e Spark
<a name="ctas-partitioning-and-bucketing-hive-and-spark-support"></a>

O mecanismo Athena versão 2 é compatível com conjuntos de dados em buckets usando o algoritmo de bucket do Hive, e o mecanismo Athena versão 3 também é compatível com o algoritmo de bucketing do Apache Spark. O bucketing Hive é o padrão. Se seu conjunto de dados for classificado em buckets usando o algoritmo Spark, use a cláusula `TBLPROPERTIES` para definir o valor da propriedade `bucketing_format` como `spark`.

**nota**  
O Athena tem um limite de 100 partições em uma consulta `CREATE TABLE AS SELECT` ([CTAS](ctas.md)). Da mesma forma, é possível adicionar apenas, no máximo, 100 partições a uma tabela de destino com uma instrução [INSERT INTO](insert-into.md).  
Se exceder essa limitação, você poderá receber a mensagem de erro HIVE\$1TOO\$1MANY\$1OPEN\$1PARTITIONS: Exceeded limit of 100 open writers for partitions/buckets (Limite excedido de 100 gravadores abertos para partições/buckets). Para contornar essa limitação, é possível usar uma instrução CTAS e uma série de instruções `INSERT INTO` que criam ou inserem até 100 partições cada. Para obter mais informações, consulte [Usar CTAS e INSERT INTO para resolver o limite de 100 partições](ctas-insert-into.md).

## Exemplo de CREATE TABLE para bucketing
<a name="ctas-partitioning-and-bucketing-bucketing-create-table-example"></a>

Para criar uma tabela para um conjunto de dados em buckets existente, use a cláusula `CLUSTERED BY (column)` seguida da cláusula `INTO N BUCKETS`. A cláusula `INTO N BUCKETS` especifica o número de buckets nos quais os dados são classificados.

No exemplo de `CREATE TABLE` a seguir, o conjunto de dados `sales` é classificado por `customer_id` em oito buckets usando o algoritmo Spark. A instrução `CREATE TABLE` usa as cláusulas`CLUSTERED BY` e `TBLPROPERTIES` para definir as propriedades adequadamente.

```
CREATE EXTERNAL TABLE sales (...) 
... 
CLUSTERED BY (`customer_id`) INTO 8 BUCKETS 
... 
TBLPROPERTIES ( 
  'bucketing_format' = 'spark' 
)
```

## Exemplo de CREATE TABLE AS (CTAS) para bucketing
<a name="ctas-partitioning-and-bucketing-bucketing-create-table-as-example"></a>

Para especificar o bucketing com `CREATE TABLE AS`, use os parâmetros `bucketed_by` e `bucket_count`, como no exemplo a seguir.

```
CREATE TABLE sales 
WITH ( 
  ... 
  bucketed_by = ARRAY['customer_id'], 
  bucket_count = 8 
) 
AS SELECT ...
```

## Exemplo de consulta de bucketing
<a name="ctas-partitioning-and-bucketing-bucketing-query-example"></a>

O exemplo de consulta a seguir pesquisa os nomes dos produtos que um cliente específico comprou ao longo de uma semana.

```
SELECT DISTINCT product_name 
FROM sales 
WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' 
AND customer_id = 'c123'
```

Se essa tabela for particionada por `sales_date` e classificada em buckets por `customer_id`, o Athena poderá calcular o bucket em que os registros do cliente estão. No máximo, o Athena lê um arquivo por partição.

# Recursos adicionais
<a name="ctas-partitioning-and-bucketing-additional-resources"></a>
+ Para obter um exemplo de `CREATE TABLE AS` que cria tabelas em bucket e particionadas, consulte [Exemplo: criar tabelas em bucket e particionadas](https://docs.aws.amazon.com/athena/latest/ug/ctas-examples.html#ctas-example-bucketed).
+ Para obter informações sobre a implementação de buckets em data lakes do AWS, incluindo o uso de uma declaração CTAS do Athena, AWS Glue para o Apache Spark e buckets para tabelas do Apache Iceberg, consulte a postagem do blog do AWS Big Data: [Optimize data layout by bucketing with Amazon Athena and AWS Glue to accelerate downstream queries](https://aws.amazon.com/blogs/big-data/optimize-data-layout-by-bucketing-with-amazon-athena-and-aws-glue-to-accelerate-downstream-queries/). 

# Particionar dados
<a name="partitions"></a>

Ao particionar os dados, você pode restringir a quantidade que cada consulta verifica, o que melhora a performance e reduz o custo. Você pode dividir seus dados em partições usando qualquer chave. Uma prática comum é particionar os dados com base no tempo, normalmente acarretando um esquema de particionamento em vários níveis. Por exemplo, um cliente que tenha dados vindos a cada hora pode optar por particionar por ano, mês, data e hora. Outro cliente, que tem dados oriundos de muitas origens diferentes, mas carregados apenas uma vez por dia, poderia particionar por um identificador de origem dos dados e data.

O Athena pode usar partições no estilo do Apache Hive, cujos caminhos de dados contêm pares de valor-chave conectados por sinais de igual (por exemplo, `country=us/...` ou `year=2021/month=01/day=26/...`). Assim, os caminhos incluem os nomes das chaves de partição e os valores que cada caminho representa. Para carregar novas partições Hive em uma tabela particionada, você pode usar o [MSCK REPAIR TABLE](msck-repair-table.md), que funciona apenas com partições no estilo Hive.

O Athena também pode usar esquemas de particionamento em estilo não Hive. Por exemplo, os logs do CloudTrail e os fluxos de entrega do Firehose usam componentes de caminho separados para componentes de data, como `data/2021/01/26/us/6fc7845e.json`. Para essas partições que não seguem o estilo do Hive, use [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) para adicionar as partições manualmente.

## Considerações e limitações
<a name="partitions-considerations-limitations"></a>

Ao usar o particionamento, lembre-se dos seguintes pontos:
+ Se você consultar uma tabela particionada e especificar a partição na cláusula `WHERE`, o Athena verificará somente os dados dessa partição.
+ Se você executar consultas em buckets do Amazon S3 com um grande número de objetos, e os dados não estiverem particionados, essas consultas poderão afetar os limites de taxa de solicitações `GET` no Amazon S3 e gerar exceções no Amazon S3. Para evitar erros, particione seus dados. Considere também ajustar suas taxas de solicitações do Amazon S3. Para obter mais informações, consulte [Padrões de design de melhores práticas: otimizar a performance do Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/request-rate-perf-considerations.html).
+ Os locais das partições que serão usados com o Athena devem aplicar o protocolo do `s3` (por exemplo, `s3://amzn-s3-demo-bucket/folder/`). No Athena, os locais que usam outros protocolos (por exemplo, `s3a://amzn-s3-demo-bucket/folder/`) resultam em falhas nas consultas `MSCK REPAIR TABLE` quando elas são executadas nas tabelas que os contêm. 
+ Verifique se o caminho do Amazon S3 está em letras minúsculas, em vez de maiúsculas e minúsculas concatenadas (por exemplo, `userid` em vez de `userId`). Se o caminho do S3 estiver em maiúsculas e minúsculas concatenadas, o `MSCK REPAIR TABLE` não adicionará as partições ao AWS Glue Data Catalog. Para obter mais informações, consulte [MSCK REPAIR TABLE](msck-repair-table.md).
+ Como `MSCK REPAIR TABLE` verifica uma pasta e as subpastas para encontrar um esquema de partição correspondente, mantenha os dados das tabelas separadas em hierarquias de pastas separadas. Por exemplo, suponha que você tenha dados na tabela 1 em `s3://amzn-s3-demo-bucket1` e dados na tabela 2 em `s3://amzn-s3-demo-bucket1/table-2-data`. Se ambas as tabelas forem particionadas por string, `MSCK REPAIR TABLE` adicionará as partições da tabela 2 à tabela 1. Para evitar isso, use estruturas de pastas separadas, como `s3://amzn-s3-demo-bucket1` e `s3://amzn-s3-demo-bucket2`. Observe que esse comportamento é consistente com o Amazon EMR e o Apache Hive.
+ Se estiver usando o AWS Glue Data Catalog com o Athena, consulte [Endpoints e cotas do AWS Glue](https://docs.aws.amazon.com/general/latest/gr/glue.html) para obter informações sobre cotas de serviço em partições por conta e por tabela. 
  + Embora o Athena ofereça suporte a consulta a tabelas do AWS Glue com 10 milhões de partições, o Athena não pode ler mais de 1 milhão de partições em uma única varredura. Nesses cenários, a indexação de partições pode ser benéfica. Para obter mais informações, consulte o artigo do Blog de Big Data da AWS, [Melhorar a performance das consultas do Amazon Athena usando índices de partição do AWS Glue Data Catalog](https://aws.amazon.com/blogs/big-data/improve-amazon-athena-query-performance-using-aws-glue-data-catalog-partition-indexes/).
+ Para solicitar um aumento de cota de partições, se estiver usando o AWS Glue Data Catalog, acesse o [console do Service Quotas para o AWS Glue](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/glue/quotas).

## Criar e carregar uma tabela com dados particionados
<a name="partitions-creating-loading"></a>

Para criar uma tabela que use partições, use a cláusula `PARTITIONED BY` na sua instrução [CREATE TABLE](create-table.md). A cláusula `PARTITIONED BY` define as chaves usadas para particionar dados, como no exemplo a seguir. A cláusula `LOCATION` especifica o local raiz dos dados particionados.

```
CREATE EXTERNAL TABLE users (
first string,
last string,
username string
)
PARTITIONED BY (id string)
STORED AS parquet
LOCATION 's3://amzn-s3-demo-bucket'
```

Depois de criar a tabela, carregue os dados nas partições para consulta. Para partições no estilo do Hive, você executa [MSCK REPAIR TABLE](msck-repair-table.md). Para partições que não seguem o estilo do Hive, use [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) para adicionar as partições manualmente.

## Preparar dados em estilo Hive e não Hive para consulta
<a name="partitions-preparing-data"></a>

As seções a seguir mostram como preparar dados de estilo do Hive e de estilo não Hive para consulta no Athena.

### Cenário 1: dados armazenados no Amazon S3 no formato Hive
<a name="scenario-1-data-already-partitioned-and-stored-on-s3-in-hive-format"></a>

Nesse cenário, as partições são armazenadas em pastas separadas no Amazon S3. Por exemplo, aqui está a listagem parcial para exemplos de impressões de anúncio exibidas pelo [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/ls.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/ls.html), que lista os objetos do S3 sob um prefixo especificado:

```
aws s3 ls s3://elasticmapreduce/samples/hive-ads/tables/impressions/

    PRE dt=2009-04-12-13-00/
    PRE dt=2009-04-12-13-05/
    PRE dt=2009-04-12-13-10/
    PRE dt=2009-04-12-13-15/
    PRE dt=2009-04-12-13-20/
    PRE dt=2009-04-12-14-00/
    PRE dt=2009-04-12-14-05/
    PRE dt=2009-04-12-14-10/
    PRE dt=2009-04-12-14-15/
    PRE dt=2009-04-12-14-20/
    PRE dt=2009-04-12-15-00/
    PRE dt=2009-04-12-15-05/
```

Aqui, os logs são armazenados com o nome da coluna (dt) definido igual a incrementos de data, hora e minuto. Quando especifica o local da pasta pai, o esquema e o nome da coluna particionada em uma DDL, o Athena pode consultar os dados nessas subpastas.

#### Criar a tabela
<a name="creating-a-table"></a>

Para gerar uma tabela com esses dados, crie uma partição com “dt”, como na seguinte instrução DDL do Athena:

```
CREATE EXTERNAL TABLE impressions (
    requestBeginTime string,
    adId string,
    impressionId string,
    referrer string,
    userAgent string,
    userCookie string,
    ip string,
    number string,
    processId string,
    browserCookie string,
    requestEndTime string,
    timers struct<modelLookup:string, requestTime:string>,
    threadId string,
    hostname string,
    sessionId string)
PARTITIONED BY (dt string)
ROW FORMAT  serde 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://elasticmapreduce/samples/hive-ads/tables/impressions/' ;
```

Esta tabela usa o serializador/desserializador JSON nativo do Hive para ler os dados JSON armazenados no Amazon S3. Para obter mais informações sobre os formatos compatíveis, consulte [Escolha de um SerDe para seus dados](supported-serdes.md).

#### Executar MSCK REPAIR TABLE
<a name="run-msck-repair-table"></a>

Depois de executar a consulta `CREATE TABLE`, execute o comando `MSCK REPAIR TABLE` no editor de consultas do Athena para carregar as partições, como no exemplo a seguir.

```
MSCK REPAIR TABLE impressions
```

Depois de executar esse comando, os dados estarão prontos para consulta.

#### Consultar os dados
<a name="query-the-data"></a>

Consulte os dados da tabela de impressões usando a coluna de partição. Veja um exemplo abaixo:

```
SELECT dt,impressionid FROM impressions WHERE dt<'2009-04-12-14-00' and dt>='2009-04-12-13-00' ORDER BY dt DESC LIMIT 100
```

Esta consulta deve mostrar dados semelhantes aos seguintes:

```
2009-04-12-13-20    ap3HcVKAWfXtgIPu6WpuUfAfL0DQEc
2009-04-12-13-20    17uchtodoS9kdeQP1x0XThKl5IuRsV
2009-04-12-13-20    JOUf1SCtRwviGw8sVcghqE5h0nkgtp
2009-04-12-13-20    NQ2XP0J0dvVbCXJ0pb4XvqJ5A4QxxH
2009-04-12-13-20    fFAItiBMsgqro9kRdIwbeX60SROaxr
2009-04-12-13-20    V4og4R9W6G3QjHHwF7gI1cSqig5D1G
2009-04-12-13-20    hPEPtBwk45msmwWTxPVVo1kVu4v11b
2009-04-12-13-20    v0SkfxegheD90gp31UCr6FplnKpx6i
2009-04-12-13-20    1iD9odVgOIi4QWkwHMcOhmwTkWDKfj
2009-04-12-13-20    b31tJiIA25CK8eDHQrHnbcknfSndUk
```

### Cenário 2: Os dados não são particionados no formato Hive
<a name="scenario-2-data-is-not-partitioned"></a>

No exemplo a seguir, o comando `aws s3 ls` mostra os logs [ELB](elasticloadbalancer-classic-logs.md) armazenados no Amazon S3. Observe como o layout de dados não usa pares `key=value` e, portanto, não está no formato Hive. (A opção `--recursive` para o comando `aws s3 ls` especifica que todos os arquivos ou objetos no diretório ou prefixo especificado serão listados.)

```
aws s3 ls s3://athena-examples-myregion/elb/plaintext/ --recursive

2016-11-23 17:54:46   11789573 elb/plaintext/2015/01/01/part-r-00000-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    8776899 elb/plaintext/2015/01/01/part-r-00001-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    9309800 elb/plaintext/2015/01/01/part-r-00002-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    9412570 elb/plaintext/2015/01/01/part-r-00003-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47   10725938 elb/plaintext/2015/01/01/part-r-00004-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    9439710 elb/plaintext/2015/01/01/part-r-00005-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47          0 elb/plaintext/2015/01/01_$folder$
2016-11-23 17:54:47    9012723 elb/plaintext/2015/01/02/part-r-00006-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    7571816 elb/plaintext/2015/01/02/part-r-00007-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    9673393 elb/plaintext/2015/01/02/part-r-00008-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   11979218 elb/plaintext/2015/01/02/part-r-00009-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48    9546833 elb/plaintext/2015/01/02/part-r-00010-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   10960865 elb/plaintext/2015/01/02/part-r-00011-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48          0 elb/plaintext/2015/01/02_$folder$
2016-11-23 17:54:48   11360522 elb/plaintext/2015/01/03/part-r-00012-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   11211291 elb/plaintext/2015/01/03/part-r-00013-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48    8633768 elb/plaintext/2015/01/03/part-r-00014-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49   11891626 elb/plaintext/2015/01/03/part-r-00015-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49    9173813 elb/plaintext/2015/01/03/part-r-00016-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49   11899582 elb/plaintext/2015/01/03/part-r-00017-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49          0 elb/plaintext/2015/01/03_$folder$
2016-11-23 17:54:50    8612843 elb/plaintext/2015/01/04/part-r-00018-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50   10731284 elb/plaintext/2015/01/04/part-r-00019-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    9984735 elb/plaintext/2015/01/04/part-r-00020-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    9290089 elb/plaintext/2015/01/04/part-r-00021-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    7896339 elb/plaintext/2015/01/04/part-r-00022-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8321364 elb/plaintext/2015/01/04/part-r-00023-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51          0 elb/plaintext/2015/01/04_$folder$
2016-11-23 17:54:51    7641062 elb/plaintext/2015/01/05/part-r-00024-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51   10253377 elb/plaintext/2015/01/05/part-r-00025-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8502765 elb/plaintext/2015/01/05/part-r-00026-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51   11518464 elb/plaintext/2015/01/05/part-r-00027-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    7945189 elb/plaintext/2015/01/05/part-r-00028-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    7864475 elb/plaintext/2015/01/05/part-r-00029-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51          0 elb/plaintext/2015/01/05_$folder$
2016-11-23 17:54:51   11342140 elb/plaintext/2015/01/06/part-r-00030-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8063755 elb/plaintext/2015/01/06/part-r-00031-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9387508 elb/plaintext/2015/01/06/part-r-00032-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9732343 elb/plaintext/2015/01/06/part-r-00033-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52   11510326 elb/plaintext/2015/01/06/part-r-00034-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9148117 elb/plaintext/2015/01/06/part-r-00035-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52          0 elb/plaintext/2015/01/06_$folder$
2016-11-23 17:54:52    8402024 elb/plaintext/2015/01/07/part-r-00036-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    8282860 elb/plaintext/2015/01/07/part-r-00037-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52   11575283 elb/plaintext/2015/01/07/part-r-00038-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53    8149059 elb/plaintext/2015/01/07/part-r-00039-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53   10037269 elb/plaintext/2015/01/07/part-r-00040-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53   10019678 elb/plaintext/2015/01/07/part-r-00041-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53          0 elb/plaintext/2015/01/07_$folder$
2016-11-23 17:54:53          0 elb/plaintext/2015/01_$folder$
2016-11-23 17:54:53          0 elb/plaintext/2015_$folder$
```

#### Executar ALTER TABLE ADD PARTITION
<a name="run-alter-table-add-partition"></a>

Como os dados não estão no formato Hive, você não pode usar o comando `MSCK REPAIR TABLE` para adicionar as partições à tabela depois de criá-la. Em vez disso, você pode usar o comando [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) para adicionar cada partição manualmente. Por exemplo, para carregar os dados em s3://athena-examples-*myregion*/elb/plaintext/2015/01/01/, execute a consulta a seguir. Observe que não é necessária uma coluna de partição separada para cada pasta do Amazon S3 e que o valor da chave da partição pode ser diferente da chave do Amazon S3.

```
ALTER TABLE elb_logs_raw_native_part ADD PARTITION (dt='2015-01-01') location 's3://athena-examples-us-west-1/elb/plaintext/2015/01/01/'
```

Se já existir uma partição, você receberá o erro de que a partição já existe. Para evitar esse erro, você pode usar a cláusula `IF NOT EXISTS`. Para obter mais informações, consulte [ALTER TABLE ADD PARTITION](alter-table-add-partition.md). Para remover uma partição, use [ALTER TABLE DROP PARTITION](alter-table-drop-partition.md). 

## Considerar a projeção de partições
<a name="partitions-partition-projection"></a>

Para evitar a necessidade de gerenciar partições, é possível usar a projeção de partições. A projeção de partição é uma opção para tabelas altamente particionadas cuja estrutura é conhecida antecipadamente. Na projeção de partições, os valores e os locais das partições são calculados a partir das propriedades da tabela que foi configurada, não da leitura de um repositório de metadados. Como os cálculos na memória são mais rápidos do que a pesquisa remota, o uso da projeção de partição pode reduzir significativamente os tempos de execução da consulta. 

Para obter mais informações, consulte [Usar projeção de partições com o Amazon Athena](partition-projection.md).

## Recursos adicionais
<a name="partitions-additional-resources"></a>
+ Para obter informações sobre opções de particionamento para dados do Firehose, consulte [Exemplo do Amazon Data Firehose](partition-projection-kinesis-firehose-example.md).
+ Também é possível automatizar partições usando o [driver JDBC](connect-with-jdbc.md). 
+ É possível usar CTAS e INSERT INTO para particionar um conjunto de dados. Para obter mais informações, consulte [Usar CTAS e INSERT INTO para ETL e análise de dados](ctas-insert-into-etl.md).

# Usar projeção de partições com o Amazon Athena
<a name="partition-projection"></a>

É possível usar a projeção de partições no Athena para acelerar o processamento de consultas de tabelas altamente particionadas e automatizar o gerenciamento de partições.

Na projeção de partições, o Athena calcula valores e localizações de partições usando as propriedades da tabela que você configura diretamente em sua tabela no AWS Glue. As propriedades da tabela permitem que o Athena “projete”, ou determine, as informações de partição necessárias em vez de fazer mais uma pesquisa de metadados demorada no AWS Glue Data Catalog. Como as operações na memória costumam ser mais rápidas do que as operações remotas, a projeção de partições pode reduzir o runtime de consultas em tabelas altamente particionadas. Dependendo das características específicas da consulta e dos dados subjacentes, a projeção de partições pode reduzir significativamente o runtime para consultas restritas na recuperação de metadados de partição.

## Noções básicas de remoção de partições versus a projeção de partições
<a name="partition-projection-pruning-vs-projection"></a>

A redução de partição coleta metadados e os “reduz” para apenas as partições que se aplicam à sua consulta. Geralmente, isso acelera as consultas. O Athena usa a redução de partição em todas as tabelas com colunas de partição, inclusive aquelas configuradas para projeção de partições.

Normalmente, ao processar consultas, o Athena faz uma chamada `GetPartitions` para o AWS Glue Data Catalog antes de reduzir a partição. Se uma tabela tiver um grande número de partições, o uso de `GetPartitions` poderá prejudicar a performance. Para que isso não aconteça, você pode usar a projeção de partições. A projeção de partições permite que o Athena evite chamar `GetPartitions` porque a configuração de projeção de partições fornece ao Athena todas as informações necessárias para criar as partições propriamente ditas.

## Usar projeção de partições
<a name="partition-projection-using"></a>

Para usar a projeção de partições, especifique os intervalos de valores de partição e os tipos de projeção para cada coluna de partição nas propriedades da tabela no AWS Glue Data Catalog ou no [metastore do Hive externo](connect-to-data-source-hive.md). Essas propriedades personalizadas na tabela permitem que o Athena saiba quais padrões de partição esperar ao executar uma consulta na tabela. Durante a execução da consulta, o Athena usa essas informações para projetar os valores de partição, em vez de recuperá-los do AWS Glue Data Catalog ou do metastore do Hive externo. Esse comportamento reduz o tempo de execução da consulta e também automatiza o gerenciamento de partições, pois acaba com a necessidade de criar manualmente partições no Athena, no AWS Glue ou no metastore do Hive externo.

**Importante**  
Habilitar a projeção de partições em uma tabela faz com que o Athena ignore os metadados de partição registrados na tabela no AWS Glue Data Catalog ou no metastore do Hive.

## Alguns casos de uso
<a name="partition-projection-use-cases"></a>

Os cenários em que a projeção de partições é útil incluem o seguinte:
+ As consultas em uma tabela altamente particionada não são concluídas com a rapidez desejada.
+ Você adiciona partições regularmente a tabelas à medida que novas partições de data ou hora são criadas em seus dados. Com a projeção de partições, você configura intervalos de datas relativos que podem ser usados à medida que novos dados chegam. 
+ Você tem dados altamente particionados no Amazon S3. Os dados não são práticos para modelar no AWS Glue Data Catalog ou no metastore do Hive, e suas consultas leem apenas pequenas partes deles.

### Estruturas de partições projetáveis
<a name="partition-projection-known-data-structures"></a>

A projeção de partições é mais facilmente configurada quando as partições seguem um padrão previsível como, mas não limitado ao seguinte:
+ **Inteiros**: qualquer sequência contínua de inteiros, como `[1, 2, 3, 4, ..., 1000]` ou `[0500, 0550, 0600, ..., 2500]`.
+ **Datas**: qualquer sequência contínua de datas ou datas e horas, como `[20200101, 20200102, ..., 20201231]` ou `[1-1-2020 00:00:00, 1-1-2020 01:00:00, ..., 12-31-2020 23:00:00]`.
+ **Valores enumerados**: um conjunto finito de valores enumerados, como códigos de aeroporto ou Regiões da AWS.
+ **Logs de AWS service (Serviço da AWS)**: normalmente, os logs de AWS service (Serviço da AWS) têm uma estrutura conhecida com um esquema de partição que você pode especificar no AWS Glue e que, portanto, o Athena pode usar na projeção de partições.

### Como personalizar o modelo de caminho de partição
<a name="partition-projection-custom-s3-storage-locations"></a>

Por padrão, o Athena cria locais de partição usando o formulário `s3://amzn-s3-demo-bucket/<table-root>/partition-col-1=<partition-col-1-val>/partition-col-2=<partition-col-2-val>/`. No entanto, se os dados estão organizados de forma diferente, o Athena oferece um mecanismo para personalizar esse modelo de caminho. Para obter as etapas, consulte [Como especificar locais de armazenamento personalizados do S3](partition-projection-setting-up.md#partition-projection-specifying-custom-s3-storage-locations).

## Considerações e limitações
<a name="partition-projection-considerations-and-limitations"></a>

As seguintes considerações se aplicam:
+ A projeção de partições elimina a necessidade de especificar partições manualmente no AWS Glue ou em um metastore do Hive externo.
+ Quando você habilita a projeção de partições em uma tabela, o Athena ignora todos os metadados de partição no AWS Glue Data Catalog ou no metastore do Hive externo referentes a essa tabela.
+ Se uma partição projetada não existir no Amazon S3, o Athena ainda a projetará. O Athena não gera um erro, mas também não retorna dados. No entanto, se muitas partições estiverem vazias, a performance poderá ser mais lenta em comparação com as partições tradicionais do AWS Glue. Se mais da metade das partições projetadas estiver vazia, é recomendado usar partições tradicionais.
+ As consultas de valores que excedem os limites de intervalo definidos para a projeção de partição não retornam erro. Em vez disso, a consulta é executada, mas não retorna nenhuma linha. Por exemplo, se você tem dados relacionados a um cronograma que começa em 2020 e está definidos como `'projection.timestamp.range'='2020/01/01,NOW'`, uma consulta como `SELECT * FROM table-name WHERE timestamp = '2019/02/02'` será concluída com êxito, mas não retornará nenhuma linha.
+ A projeção de partições somente pode ser usada quando a tabela é consultada pelo Athena. Se a mesma tabela for lida por meio de outro serviço, como o Amazon Redshift Spectrum, o Athena for Spark ou o Amazon EMR, os metadados de partição padrão serão usados.
+ Como a projeção de partições é um recurso somente DML, `SHOW PARTITIONS` não lista as partições projetadas pelo Athena, mas que não estão registradas no catálogo do AWS Glue ou no metastore do Hive externo. 
+ O Athena não usa as propriedades de tabela de visualizações como configuração para a projeção de partições. Para contornar essa limitação, configure e habilite a projeção de partições nas propriedades das tabelas mencionadas nas visualizações.

## Vídeo
<a name="partition-projection-video"></a>

O vídeo a seguir mostra como usar a projeção de partições para melhorar a performance das suas consultas no Athena.

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/iUD5pPpcyZk/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/iUD5pPpcyZk)


**Topics**
+ [

## Noções básicas de remoção de partições versus a projeção de partições
](#partition-projection-pruning-vs-projection)
+ [

## Usar projeção de partições
](#partition-projection-using)
+ [

## Alguns casos de uso
](#partition-projection-use-cases)
+ [

## Considerações e limitações
](#partition-projection-considerations-and-limitations)
+ [

## Vídeo
](#partition-projection-video)
+ [

# Configurar a projeção de partições
](partition-projection-setting-up.md)
+ [

# Tipos compatíveis para projeção de partições
](partition-projection-supported-types.md)
+ [

# Usar particionamento de ID dinâmico
](partition-projection-dynamic-id-partitioning.md)
+ [

# Exemplo do Amazon Data Firehose
](partition-projection-kinesis-firehose-example.md)

# Configurar a projeção de partições
<a name="partition-projection-setting-up"></a>

A configuração da projeção de partições nas propriedades de uma tabela é um processo de duas etapas:

1. Especifique os intervalos de dados e os padrões relevantes para cada coluna de partição ou use um modelo personalizado.

1. Habilite a projeção de partições para a tabela.

**nota**  
Antes de adicionar propriedades de projeção de partição para uma tabela existente, a coluna de partição para a qual você está configurando as propriedades de projeção de partição já deve existir no esquema da tabela. Caso a coluna de partição ainda não exista, você deverá adicionar manualmente uma coluna de partição à tabela existente. O AWS Glue não executa esta etapa para você de forma automática. 

Esta seção mostra como definir as propriedades de tabela para o AWS Glue. Para defini-las, você pode usar o console do AWS Glue, as consultas [CREATE TABLE](create-table.md) do Athena ou as operações de [AWS Glue API](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api.html). O procedimento a seguir mostra como definir as propriedades no console do AWS Glue.

**Para configurar e habilitar a projeção de partições usando o console do AWS Glue**

1. Faça login no Console de gerenciamento da AWS e abra o console do AWS Glue em [https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/).

1. Escolha a guia **Tabelas**.

   Na guia **Tabelas**, você pode editar tabelas existentes ou escolher **Adicionar tabelas** para criar novas tabelas. Para obter informações sobre como adicionar tabelas manualmente ou com um crawler, consulte [Trabalhar com tabelas no console do AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/console-tables.html) no *Guia do desenvolvedor do AWS Glue*.

1. Na lista de tabelas, escolha o link para a tabela que você deseja editar.  
![\[No console do AWS Glue, escolha uma tabela para editar.\]](http://docs.aws.amazon.com/pt_br/athena/latest/ug/images/partition-projection-1.png)

1. Selecione **Actions** (Ações), **Edit** (Editar).

1. Na página **Edit table** (Editar tabela), na seção **Table properties** (Propriedades da tabela), para cada coluna particionada, adicione o seguinte par de chave-valor:

   1. Em **Chave**, adicione `projection.columnName.type`.

   1. Em **Valor**, adicione um dos tipos compatíveis: `enum`, `integer`, `date` ou `injected`. Para obter mais informações, consulte [Tipos compatíveis para projeção de partições](partition-projection-supported-types.md).

1. Seguindo as orientações em [Tipos compatíveis para projeção de partições](partition-projection-supported-types.md), adicione outros pares de chave-valor de acordo com seus requisitos de configuração.

   O exemplo de configuração de tabela a seguir configura a coluna ‭`year`‬ para projeção de partições, restringindo os valores que podem ser retornados a um intervalo de 2010 a 2016.  
![\[Configuração da projeção de partições para uma coluna de partição nas propriedades de tabela do console do AWS Glue.\]](http://docs.aws.amazon.com/pt_br/athena/latest/ug/images/partition-projection-3.png)

1. Adicione um par de chave-valor para habilitar a projeção de partições. Em **Chave**, insira `projection.enabled` e, em **Valor**, insira `true`.
**nota**  
Você pode desativar a projeção de partições nessa tabela a qualquer momento definindo `projection.enabled` como `false`.

1. Quando terminar, escolha **Salvar**.

1. No editor de consultas do Athena, faça uma consulta de teste nas colunas de tabela que você configurou.

   A consulta de exemplo a seguir usa `SELECT DISTINCT` para retornar os valores exclusivos da coluna `year`. O banco de dados contém dados de 1987 a 2016, mas a propriedade ‭`projection.year.range` restringe os valores retornados para os anos 2010 a 2016.  
![\[Consultando uma coluna que usa projeção de partições.\]](http://docs.aws.amazon.com/pt_br/athena/latest/ug/images/partition-projection-5.png)
**nota**  
Se você definir `projection.enabled` como `true`, mas não conseguir configurar uma ou mais colunas de partição, receberá uma mensagem de erro como a seguinte:  
`HIVE_METASTORE_ERROR: Table database_name.table_name is configured for partition projection, but the following partition columns are missing projection configuration: [column_name] (table database_name.table_name)`.

## Como especificar locais de armazenamento personalizados do S3
<a name="partition-projection-specifying-custom-s3-storage-locations"></a>

Ao editar as propriedades de tabela no AWS Glue, você também pode especificar um modelo de caminho do Amazon S3 personalizado para as partições projetadas. Um modelo personalizado permite que o Athena mapeie corretamente os valores de partição para os locais de arquivo personalizados do Amazon S3 que não seguem o padrão `.../column=value/...`. 

O uso de um modelo personalizado é opcional. No entanto, se você usar um modelo personalizado, o modelo deverá conter um espaço reservado para cada coluna de partição. Os locais baseados em modelo devem terminar com uma barra para que os arquivos de dados particionados sejam armazenados em uma “pasta” por partição.

**Como especificar um modelo de local de partição personalizado**

1. Seguindo as etapas para [configurar e habilitar a projeção de partições usando o console do AWS Glue](#partition-projection-setting-up-procedure), adicione outro par de chave-valor que especifique um modelo personalizado da seguinte forma:

   1. Em **Chave**, digite `storage.location.template`.

   1. Em **Valor**, especifique um local que inclua um espaço reservado para cada coluna de partição. Termine cada espaço reservado (e o próprio caminho do S3) com uma barra única.

      Os valores de modelo de exemplo a seguir assumem uma tabela com colunas de partição `a`, `b` e `c`.

      ```
      s3://amzn-s3-demo-bucket/table_root/a=${a}/${b}/some_static_subdirectory/${c}/      
      ```

      ```
      s3://amzn-s3-demo-bucket/table_root/c=${c}/${b}/some_static_subdirectory/${a}/${b}/${c}/${c}/      
      ```

      Para a mesma tabela, o valor de modelo de exemplo a seguir é inválido porque não contém nenhum espaço reservado para a coluna `c`.

      ```
      s3://amzn-s3-demo-bucket/table_root/a=${a}/${b}/some_static_subdirectory/         
      ```

1. Escolha **Aplicar**.

# Tipos compatíveis para projeção de partições
<a name="partition-projection-supported-types"></a>

Uma tabela pode ter qualquer combinação dos tipos `enum`, `integer`, `date,` ou `injected` de coluna de partição.

## Tipo enum
<a name="partition-projection-enum-type"></a>

Use o tipo `enum` para colunas de partição cujos valores são membros de um conjunto enumerado (por exemplo, códigos de aeroporto ou Regiões da AWS).

Defina as propriedades da partição na tabela da seguinte forma:


****  

| Nome da propriedade | Exemplos de valores | Descrição | 
| --- | --- | --- | 
| projection.columnName.type |  `enum`  | Obrigatório. O tipo de projeção a ser usado para a coluna columnName. O valor deve ser enum (sem diferenciar maiúsculas e minúsculas) para sinalizar o uso do tipo de enumeração. Espaços em branco iniciais e finais são permitidos. | 
| projection.columnName.values |  `A,B,C,D,E,F,G,Unknown`  | Obrigatório. Uma lista separada por vírgulas de valores de partição enumerados para a coluna columnName. Qualquer espaço em branco é considerado parte de um valor de enumeração. | 

**nota**  
Como prática recomendada, limite o uso de projeções de partições com base em `enum` a no máximo algumas dúzias. Embora não haja um limite específico para projeções `enum`, o tamanho total dos metadados da sua tabela não pode exceder o limite do AWS Glue de cerca de 1 MB quando compactado com gzip. Esse limite é compartilhado entre as partes principais da tabela, como nomes de colunas, local, formato de armazenamento etc. Se você usar mais de algumas dúzias de IDs exclusivos em sua projeção `enum`, considere uma abordagem alternativa, como criar buckets de um número menor de valores exclusivos em um campo substituto. Ao compensar a cardinalidade, você pode controlar o número de valores exclusivos no campo `enum`. 

## Tipo integer
<a name="partition-projection-integer-type"></a>

Use o tipo integer para colunas de partição cujos valores possíveis são interpretáveis como inteiros dentro de um intervalo definido. As colunas integer projetadas estão atualmente limitadas ao intervalo de um Java assinado longo (-263 a 263-1, ambos incluídos).


****  

| Nome da propriedade | Exemplos de valores | Descrição | 
| --- | --- | --- | 
| projection.columnName.type |  `integer`  | Obrigatório. O tipo de projeção a ser usado para a coluna columnName. O valor deve ser integer (sem diferenciar maiúsculas e minúsculas) para sinalizar o uso do tipo de inteiro. Espaços em branco iniciais e finais são permitidos. | 
| projection.columnName.range |  `0,10` `-1,8675309` `0001,9999`  | Obrigatório. Uma lista separada por vírgulas de dois elementos que fornece os valores de intervalo mínimo e máximo a serem retornados por consultas na coluna columnName. Observe que os valores devem ser separados por uma vírgula, não por um hífen. Esses valores são inclusivos, podem ser negativos e podem ter zeros à esquerda. Espaços em branco iniciais e finais são permitidos. | 
| projection.columnName.interval |  `1` `5`  | Opcional. Um inteiro positivo que especifica o intervalo entre valores de partição sucessivos para a coluna columnName. Por exemplo, um valor range de “1,3" com um valor interval de “1" produz os valores 1, 2 e 3. O mesmo valor range com um valor interval de “2" produz os valores 1 e 3, ignorando 2. Espaços em branco iniciais e finais são permitidos. O padrão é 1. | 
| projection.columnName.digits |  `1` `5`  | Opcional. Um inteiro positivo que especifica o número de dígitos a serem incluídos na representação final do valor da partição para a coluna columnName. Por exemplo, um valor range de “1,3" que tem um valor digits de “1" produz os valores 1, 2 e 3. O mesmo valor range com um valor digits de “2" produz os valores 01, 02 e 03. Espaços em branco iniciais e finais são permitidos. O padrão é nenhum número estático de dígitos e nenhum zero à esquerda. | 

## Tipo date
<a name="partition-projection-date-type"></a>

Use o tipo date para colunas de partição cujos valores são interpretáveis como datas (com horas opcionais) dentro de um intervalo definido.

**Importante**  
As colunas date projetadas são geradas no Horário Universal Coordenado (UTC) no tempo de execução da consulta.


****  

| Nome da propriedade | Exemplos de valores | Descrição | 
| --- | --- | --- | 
| projection.columnName.type |  `date`  | Obrigatório. O tipo de projeção a ser usado para a coluna columnName. O valor deve ser date (sem diferenciar maiúsculas e minúsculas) para sinalizar o uso do tipo de data. Espaços em branco iniciais e finais são permitidos. | 
| projection.columnName.range |  `201701,201812` `01-01-2010,12-31-2018` `NOW-3YEARS,NOW` `201801,NOW+1MONTH`  |  Obrigatório. Uma lista separada por vírgulas de dois elementos que fornece os valores `range` mínimo e máximo para a coluna *columnName*. Esses valores são inclusivos e podem usar qualquer formato compatível com os tipos de data `java.time.*` em Java. Os valores mínimo e máximo devem usar o mesmo formato. O formato especificado na propriedade `.format` deve ser o formato usado para esses valores. Essa coluna também pode conter strings de data relativas, formatadas neste padrão de expressão regular: `\s*NOW\s*(([\+\-])\s*([0-9]+)\s*(YEARS?\|MONTHS?\|WEEKS?\|DAYS?\|HOURS?\|MINUTES?\|SECONDS?)\s*)?` Espaços em branco são permitidos. No entanto, em literais de data, eles são considerados parte das strings de data em si.  | 
| projection.columnName.format |  `yyyyMM` `dd-MM-yyyy` `dd-MM-yyyy-HH-mm-ss`  | Obrigatório. Uma string de formato de data baseada no formato de data Java [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html). Pode ser qualquer tipo Java.time.\$1 compatível. | 
| projection.columnName.interval |  `1` `5`  |  Um inteiro positivo que especifica o intervalo entre valores de partição sucessivos para a coluna *columnName*. Por exemplo, um valor `range` de `2017-01,2018-12` com um valor `interval` de `1` e um valor `interval.unit` de `MONTHS` produz os valores 2017-01, 2017-02, 2017-03 e assim por diante. O mesmo valor `range` com um valor `interval` de `2` e um valor `interval.unit` de `MONTHS` produz os valores 2017-01, 2017-03, 2017-05 e assim por diante. Espaços em branco iniciais e finais são permitidos. Quando as datas fornecidas são com precisão de um dia ou um mês, o `interval` é opcional e o padrão é 1 dia ou 1 mês, respectivamente. Caso contrário, o `interval` será obrigatório.  | 
| projection.columnName.interval.unit |  `YEARS` `MONTHS` `WEEKS` `DAYS` `HOURS` `MINUTES` `SECONDS` `MILLIS`  |  Uma palavra de unidade de tempo que representa a forma serializada de uma [ChronoUnit](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html). Os valores possíveis são `YEARS`, `MONTHS`, `WEEKS`, `DAYS`, `HOURS`, `MINUTES`, `SECONDS` ou `MILLIS`. Esses valores diferenciam maiúsculas de minúsculas. Quando as datas fornecidas são com precisão de um dia ou um mês, o `interval.unit` é opcional e o padrão é 1 dia ou 1 mês, respectivamente. Caso contrário, `interval.unit` será obrigatório.  | 

**Example - Particionamento por mês**  
O exemplo de configuração da tabela a seguir particiona os dados por mês, de 2015 até o presente.  

```
'projection.month.type'='date', 
'projection.month.format'='yyyy-MM', 
'projection.month.interval'='1', 
'projection.month.interval.unit'='MONTHS', 
'projection.month.range'='2015-01,NOW', 
...
```

## Tipo injected
<a name="partition-projection-injected-type"></a>

Use o tipo injetado para colunas de partição com valores possíveis que não podem ser gerados processualmente dentro de algum intervalo lógico, mas que são fornecidos na cláusula `WHERE` de uma consulta como um único valor.

É importante ter em mente os seguintes pontos:
+ Consultas em colunas injetadas falharão se uma expressão de filtro não for fornecida para cada coluna injetada.
+ Consultas com vários valores para uma expressão de filtro em uma coluna injetada só terão êxito se os valores forem disjuntos.
+ Somente colunas do tipo `string` são permitidas.
+ Quando você usa a cláusula `WHERE IN` com uma coluna de partição injetada, há um limite de 1.000 valores que podem ser especificados na lista `IN`. Para consultar um conjunto de dados com mais de 1.000 partições para uma coluna injetada, divida a consulta em várias consultas menores, cada uma com até 1.000 valores na cláusula `WHERE IN`, e, em seguida, agregue os resultados.


****  

| Nome da propriedade | Valor | Descrição | 
| --- | --- | --- | 
| projection.columnName.type |  `injected`  | Obrigatório. O tipo de projeção a ser usado para a coluna columnName. Somente o tipo string é permitido. O valor especificado deve ser injected (sem diferenciação de maiúsculas e minúsculas). Espaços em branco iniciais e finais são permitidos. | 

Para obter mais informações, consulte [Quando usar o tipo de projeção `injected`](partition-projection-dynamic-id-partitioning.md#partition-projection-injection).

# Usar particionamento de ID dinâmico
<a name="partition-projection-dynamic-id-partitioning"></a>

Quando os dados são particionados por uma propriedade com alta cardinalidade ou quando os valores não podem ser conhecidos antecipadamente, é possível usar o tipo de projeção `injected`. Exemplos dessas propriedades são os nomes de usuário e os IDs de dispositivos ou de produtos. Quando você usa o tipo de projeção `injected` para configurar uma chave de partição, o Athena usa valores da própria consulta para calcular o conjunto de partições que serão lidas.

Para que o Athena possa executar uma consulta em uma tabela que tem uma chave de partição configurada com o tipo de projeção `injected`, o seguinte deve ser verdadeiro:
+ A consulta deve incluir, no mínimo, um valor para a chave de partição.
+ Os valores devem ser literais ou expressões que possam ser avaliadas sem a necessidade de leitura de dados.

Se algum desses critérios não for atendido, a consulta falhará e apresentará o seguinte erro:

CONSTRAINT\$1VIOLATION: para a coluna de partição projetada injetada *column\$1name*, a cláusula WHERE deve conter somente condições de igualdade estática e pelo menos uma dessas condições deve estar presente.

## Quando usar o tipo de projeção `injected`
<a name="partition-projection-injection"></a>

Imagine que você tem um conjunto de dados que consiste em eventos de dispositivos de IoT, os quais são particionados nos IDs dos dispositivos. Esse conjunto de dados tem as seguintes características:
+ Os IDs dos dispositivos são gerados de forma aleatória.
+ Novos dispositivos são provisionados com frequência.
+ Atualmente, existem centenas de milhares de dispositivos e, no futuro, haverá milhões.

Esse conjunto de dados é complexo de gerenciar usando metastores tradicionais. É difícil manter as partições sincronizadas entre o armazenamento de dados e o metastore, e a filtragem de partições pode ser lenta durante o planejamento da consulta. Entretanto, se você configurar uma tabela para usar a projeção de partição e usar o tipo de projeção `injected`, obterá duas vantagens: não precisará gerenciar partições no metastore e as consultas não precisarão procurar metadados de partições.

O exemplo `CREATE TABLE`, apresentado a seguir, cria uma tabela para o conjunto de dados de eventos do dispositivo que acabamos de descrever. A tabela usa o tipo de projeção “injected”.

```
CREATE EXTERNAL TABLE device_events (
  event_time TIMESTAMP,
  data STRING,
  battery_level INT
)
PARTITIONED BY (
  device_id STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
  "projection.enabled" = "true",
  "projection.device_id.type" = "injected",
  "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${device_id}"
)
```

O exemplo de consulta apresentado a seguir pesquisa o número de eventos recebidos de três dispositivos específicos ao longo de 12 horas.

```
SELECT device_id, COUNT(*) AS events
FROM device_events
WHERE device_id IN (
  '4a770164-0392-4a41-8565-40ed8cec737e',
  'f71d12cf-f01f-4877-875d-128c23cbde17',
  '763421d8-b005-47c3-ba32-cc747ab32f9a'
)
AND event_time BETWEEN TIMESTAMP '2023-11-01 20:00' AND TIMESTAMP '2023-11-02 08:00'
GROUP BY device_id
```

Quando você executa essa consulta, o Athena visualiza os três valores para a chave de partição `device_id` e os usa para calcular os locais das partições. O Athena usa os valores com a propriedade `storage.location.template` para gerar os seguintes locais:
+ `s3://amzn-s3-demo-bucket/prefix/4a770164-0392-4a41-8565-40ed8cec737e`
+ `s3://amzn-s3-demo-bucket/prefix/f71d12cf-f01f-4877-875d-128c23cbde17`
+ `s3://amzn-s3-demo-bucket/prefix/763421d8-b005-47c3-ba32-cc747ab32f9a`

Se você omitir a propriedade `storage.location.template` da configuração da projeção de partição, o Athena usará o particionamento no estilo Hive para projetar os locais de partições com base no valor em `LOCATION` (por exemplo, `s3://amzn-s3-demo-bucket/prefix/device_id=4a770164-0392-4a41-8565-40ed8cec737e`).

# Exemplo do Amazon Data Firehose
<a name="partition-projection-kinesis-firehose-example"></a>

Quando você usa o Firehose para entregar dados ao Amazon S3, a configuração padrão grava objetos com chaves semelhantes ao seguinte exemplo:

```
s3://amzn-s3-demo-bucket/prefix/yyyy/MM/dd/HH/file.extension
```

Para criar uma tabela do Athena que encontre as partições automaticamente no momento da consulta, em vez de precisar adicioná-las ao AWS Glue Data Catalog à medida que novos dados chegam, você pode usar a projeção de partições.

O exemplo de `CREATE TABLE` a seguir usa a configuração padrão do Firehose.

```
CREATE EXTERNAL TABLE my_ingested_data (
 ...
)
...
PARTITIONED BY (
 datehour STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.datehour.type" = "date",
 "projection.datehour.format" = "yyyy/MM/dd/HH",
 "projection.datehour.range" = "2021/01/01/00,NOW",
 "projection.datehour.interval" = "1",
 "projection.datehour.interval.unit" = "HOURS",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${datehour}/"
)
```

A cláusula `TBLPROPERTIES` na instrução `CREATE TABLE` diz ao Athena o seguinte:
+ Usar projeção de partições ao consultar a tabela
+ A chave de partição `datehour` é do tipo `date` (que inclui um horário opcional)
+ Como as datas são formatadas
+ O intervalo dos períodos de datas. Observe que os valores devem ser separados por uma vírgula, não por um hífen.
+ Onde encontrar os dados no Amazon S3.

Quando você consulta a tabela, o Athena calcula os valores para `datehour` e usa o modelo de local de armazenamento para gerar uma lista de locais de partição.

**Topics**
+ [

# Como usar o tipo `date`.
](partition-projection-kinesis-firehose-example-using-the-date-type.md)
+ [

# Como escolher chaves de partição
](partition-projection-kinesis-firehose-example-choosing-partition-keys.md)
+ [

# Como usar prefixos personalizados e particionamento dinâmico
](partition-projection-kinesis-firehose-example-using-custom-prefixes-and-dynamic-partitioning.md)

# Como usar o tipo `date`.
<a name="partition-projection-kinesis-firehose-example-using-the-date-type"></a>

Quando você usa o tipo `date` para a chave de partição projetada, deve especificar um intervalo. Como não há dados para datas antes da criação do fluxo de entrega do Firehose, você pode usar a data de criação como o início. E como você não tem dados para datas no futuro, pode usar o token especial `NOW` como fim.

No exemplo `CREATE TABLE`, a data de início é especificada como 1º de janeiro de 2021 à meia-noite UTC.

**nota**  
Configure um intervalo que corresponda o mais exatamente possível aos seus dados para que o Athena procure apenas partições existentes.

Quando uma consulta é executada na tabela de amostra, o Athena usa as condições na chave de partição `datehour` em combinação com o intervalo para gerar valores. Considere a seguinte consulta:

```
SELECT *
FROM my_ingested_data
WHERE datehour >= '2020/12/15/00'
AND datehour < '2021/02/03/15'
```

A primeira condição na consulta `SELECT` usa uma data antes do início do intervalo de datas especificado pela instrução `CREATE TABLE`. Como a configuração de projeção de partições não especifica nenhuma partição para datas antes de 1º de janeiro de 2021, o Athena procura dados somente nos locais a seguir e ignora as datas anteriores na consulta.

```
s3://amzn-s3-demo-bucket/prefix/2021/01/01/00/
s3://amzn-s3-demo-bucket/prefix/2021/01/01/01/
s3://amzn-s3-demo-bucket/prefix/2021/01/01/02/
...
s3://amzn-s3-demo-bucket/prefix/2021/02/03/12/
s3://amzn-s3-demo-bucket/prefix/2021/02/03/13/
s3://amzn-s3-demo-bucket/prefix/2021/02/03/14/
```

Da mesma forma, se a consulta fosse executada em uma data e hora antes de 3 de fevereiro de 2021 às 15:00, a última partição refletiria a data e a hora atuais, não a data e a hora na condição da consulta.

Se você quiser consultar os dados mais recentes, pode aproveitar o fato de que Athena não gera datas futuras e especificar apenas uma `datehour` de início, como no exemplo a seguir.

```
SELECT *
FROM my_ingested_data
WHERE datehour >= '2021/11/09/00'
```

# Como escolher chaves de partição
<a name="partition-projection-kinesis-firehose-example-choosing-partition-keys"></a>

Você pode especificar como a projeção de partições mapeia os locais de partição para chaves de partição. No exemplo da seção anterior para `CREATE TABLE`, a data e o horário foram combinados em uma chave de partição chamada “datehour”, mas outros esquemas são possíveis. Por exemplo, você também pode configurar uma tabela com chaves de partição separadas por ano, mês, dia e hora. 

No entanto, dividir datas em ano, mês e dia significa que o tipo de projeção de partição `date` não pode ser usado. Uma alternativa é separar a data do horário para ainda aproveitar o tipo de projeção da partição `date`, mas facilitar a leitura das consultas que especificam intervalos de horas.

Com isso em mente, o exemplo `CREATE TABLE` a seguir separa a data da hora. Como `date` é uma palavra reservada em SQL, o exemplo usa `day` como nome da chave de partição que representa a data.

```
CREATE EXTERNAL TABLE my_ingested_data2 (
 ...
)
...
PARTITIONED BY (
 day STRING,
 hour INT
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.day.type" = "date",
 "projection.day.format" = "yyyy/MM/dd",
 "projection.day.range" = "2021/01/01,NOW",
 "projection.day.interval" = "1",
 "projection.day.interval.unit" = "DAYS",
 "projection.hour.type" = "integer",
 "projection.hour.range" = "0,23",
 "projection.hour.digits" = "2",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${day}/${hour}/"
)
```

No exemplo de instrução `CREATE TABLE`, a hora é uma chave de partição separada, configurada como um inteiro. A configuração para a chave de partição de hora especifica o intervalo de 0 a 23 e que a hora deverá ser formatada com dois dígitos quando o Athena gerar os locais de partições.

Uma consulta para a tabela `my_ingested_data2` poderia ser semelhante a esta:

```
SELECT *
FROM my_ingested_data2
WHERE day = '2021/11/09'
AND hour > 3
```

## Noções básicas de chave de partição e tipos de dados de projeção de partições
<a name="partition-projection-kinesis-firehose-example-partition-key-types-and-partition-projection-types"></a>

Observe que a chave `datehour` no primeiro exemplo de `CREATE TABLE` é configurada como `date` na configuração de projeção de partições, mas o tipo de chave de partição é `string`. O mesmo vale para `day` no segundo exemplo. Os tipos na configuração de projeção de partições apenas dizem ao Athena como formatar os valores quando ele gera os locais de partição. Os tipos especificados não alteram o tipo da chave de partição. Em consultas, `datehour` e `day` são do tipo `string`.

Quando uma consulta inclui uma condição como `day = '2021/11/09'`, o Athena analisa a sequência do lado direito da expressão usando o formato de data especificado na configuração de projeção de partições. Depois que o Athena verifica se a data está dentro do intervalo configurado, ele usa o formato de data novamente para inserir a data como uma sequência no modelo de local de armazenamento.

Da mesma forma, para uma condição de consulta como `day > '2021/11/09'`, o Athena analisa o lado direito e gera uma lista de todas as datas correspondentes dentro do intervalo configurado. Em seguida, ele usa o formato de data para inserir cada data no modelo de local de armazenamento para criar a lista de locais de partição.

Escrever a mesma condição que `day > '2021-11-09'` ou `day > DATE '2021-11-09'` não funciona. No primeiro caso, o formato de data não corresponde (observe os hifens em vez de barras) e, no segundo caso, os tipos de dados não correspondem.

# Como usar prefixos personalizados e particionamento dinâmico
<a name="partition-projection-kinesis-firehose-example-using-custom-prefixes-and-dynamic-partitioning"></a>

É possível configurar o Firehose com [prefixos personalizados](https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html) e [particionamento dinâmico](https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning.html). Usando esses recursos, você pode configurar as chaves do Amazon S3 e configurar esquemas de particionamento que suportem melhor seu caso de uso. Você também pode usar a projeção de partições com esses esquemas de particionamento e configurá-los de acordo.

Por exemplo, você pode usar o recurso de prefixo personalizado para obter chaves do Amazon S3 com datas em formato ISO em vez do esquema padrão de `yyyy/MM/dd/HH`.

Você também pode combinar prefixos personalizados com particionamento dinâmico para extrair uma propriedade como `customer_id` das mensagens do Firehose, como no exemplo a seguir.

```
prefix/!{timestamp:yyyy}-!{timestamp:MM}-!{timestamp:dd}/!{partitionKeyFromQuery:customer_id}/
```

Com esse prefixo do Amazon S3, o fluxo de entrega do Firehose gravaria objetos em chaves como `s3://amzn-s3-demo-bucket/prefix/2021-11-01/customer-1234/file.extension`. Para uma propriedade como `customer_id`, na qual os valores podem não ser conhecidos com antecedência, você pode usar o tipo de projeção de partições `injected` e usar uma instrução `CREATE TABLE` como a seguinte:

```
CREATE EXTERNAL TABLE my_ingested_data3 (
 ...
)
...
PARTITIONED BY (
 day STRING,
 customer_id STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.day.type" = "date",
 "projection.day.format" = "yyyy-MM-dd",
 "projection.day.range" = "2021-01-01,NOW",
 "projection.day.interval" = "1",
 "projection.day.interval.unit" = "DAYS",
 "projection.customer_id.type" = "injected",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${day}/${customer_id}/"
)
```

Quando você consulta uma tabela que tem uma chave de partição do tipo `injected`, sua consulta deve incluir um valor para essa chave de partição. Uma consulta para a tabela `my_ingested_data3` poderia ser semelhante a esta:

```
SELECT *
FROM my_ingested_data3
WHERE day BETWEEN '2021-11-01' AND '2021-11-30'
AND customer_id = 'customer-1234'
```

## Usar o tipo DATE para a chave de partição do dia
<a name="partition-projection-kinesis-firehose-example-iso-formatted-dates"></a>

Como os valores para chave de partição `day` são em formato ISO, você também pode usar o tipo `DATE`, em vez de `STRING`, para a chave de partição de dia, como no exemplo a seguir:

```
PARTITIONED BY (day DATE, customer_id STRING)
```

Quando você consulta, essa estratégia permite que você use funções de data na chave de partição sem análise ou conversão, como no exemplo a seguir:

```
SELECT *
FROM my_ingested_data3
WHERE day > CURRENT_DATE - INTERVAL '7' DAY
AND customer_id = 'customer-1234'
```

**nota**  
A especificação de uma chave de partição do tipo `DATE` pressupõe que você usou o atributo [custom prefix](https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html) para criar chaves do Amazon S3 que tenham datas no formato ISO. Caso esteja usando o formato padrão de `yyyy/MM/dd/HH` do Firehose, você deverá especificar a chave de partição com o tipo `string`, mesmo que a propriedade da tabela correspondente seja do tipo `date`, como no seguinte exemplo:  

```
PARTITIONED BY ( 
  `mydate` string)
TBLPROPERTIES (
  'projection.enabled'='true', 
   ...
  'projection.mydate.type'='date',
  'storage.location.template'='s3://amzn-s3-demo-bucket/prefix/${mydate}')
```

# Prevenir o controle de utilização do Amazon S3
<a name="performance-tuning-s3-throttling"></a>

O controle de utilização é o processo de limitar sua taxa de uso de um serviço, uma aplicação ou um sistema. Na AWS, você pode usar o controle de utilização para evitar o uso excessivo do serviço Amazon S3 e aumentar a disponibilidade e a capacidade de resposta do Amazon S3 para todos os usuários. Porém, como o controle de utilização limita a taxa de transferências de dados de entrada e saída do Amazon S3, é importante tentar evitar que suas interações sejam limitadas.

Conforme apontado no capítulo de [ajuste de performance](performance-tuning.md), as otimizações podem depender de suas decisões de nível de serviço, de como você estrutura suas tabelas e dados e de como você escreve suas consultas.

**Topics**
+ [

# Reduzir o controle de utilização no nível de serviço
](performance-tuning-s3-throttling-reduce-throttling-at-the-service-level.md)
+ [

# Otimizar suas tabelas
](performance-tuning-s3-throttling-optimizing-your-tables.md)
+ [

# Otimizar suas consultas
](performance-tuning-s3-throttling-optimizing-queries.md)

# Reduzir o controle de utilização no nível de serviço
<a name="performance-tuning-s3-throttling-reduce-throttling-at-the-service-level"></a>

Para evitar o controle de utilização do Amazon S3 no nível do serviço, é possível monitorar o uso e ajustar as [cotas de serviço](https://docs.aws.amazon.com/general/latest/gr/s3.html#limits_s3) ou usar certas técnicas, como particionamento. Estas são algumas das condições que podem levar ao controle de utilização:
+ **Exceder os limites de solicitação de API da conta**: o Amazon S3 tem limites de solicitação de API padrão baseados no tipo e no uso da conta. Se você exceder o número máximo de solicitações por segundo para um único prefixo, as solicitações poderão ser limitadas para evitar a sobrecarga do serviço Amazon S3.
+ **Particionamento de dados insuficiente**: se você não particionar os dados corretamente e transferir uma grande quantidade de dados, o Amazon S3 poderá limitar as solicitações. Para obter mais informações sobre particionamento, consulte a seção [Usar particionamento](performance-tuning-s3-throttling-optimizing-your-tables.md#performance-tuning-s3-throttling-use-partitioning) deste documento.
+ **Grande quantidade de objetos pequenos**: se possível, evite uma grande quantidade de arquivos pequenos. O Amazon S3 tem um limite de [5500 solicitações GET](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html) por segundo por prefixo particionado, e suas consultas do Athena compartilham esse mesmo limite. Se você verificar milhões de objetos pequenos em uma única consulta, provavelmente o Amazon S3 limitará a consulta.

Para evitar verificação em excesso, você pode usar o recurso ETL do AWS Glue para compactar periodicamente os arquivos ou particionar a tabela e adicionar filtros de chave de partição. Para obter mais informações, consulte os recursos a seguir.
+ [Como posso configurar um trabalho de ETL do AWS Glue para gerar arquivos maiores?](https://aws.amazon.com/premiumsupport/knowledge-center/glue-job-output-large-files/) (*AWS Central de conhecimento da*)
+ [Ler arquivos de entrada em grupos maiores](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html) (*Guia do desenvolvedor do AWS Glue*)

# Otimizar suas tabelas
<a name="performance-tuning-s3-throttling-optimizing-your-tables"></a>

Caso você encontre problemas de controle de utilização, é importante estruturar os dados. Embora o Amazon S3 consiga lidar com grandes quantidades de dados, às vezes o controle de utilização ocorre devido à forma como os dados são estruturados.

As seções a seguir oferecem algumas sugestões sobre como estruturar dados no Amazon S3 para evitar problemas de controle de utilização.

## Usar particionamento
<a name="performance-tuning-s3-throttling-use-partitioning"></a>

É possível usar o particionamento para reduzir o controle de utilização limitando a quantidade de dados que precisam ser acessados a qualquer momento. Ao particionar dados em colunas específicas, você pode distribuir as solicitações de maneira uniforme entre vários objetos e reduzir o número de solicitações para um único objeto. Reduzir a quantidade de dados que devem ser verificados melhora a performance da consulta e reduz os custos.

Ao criar uma tabela, você pode definir partições que atuam como colunas virtuais. Para criar uma tabela com partições em uma instrução `CREATE TABLE`, use a cláusula `PARTITIONED BY (column_name data_type)` para definir as chaves para particionar dados.

Para restringir as partições verificadas por uma consulta, é possível especificá-las como predicados em uma cláusula `WHERE` da consulta. Portanto, colunas usadas como filtros com frequência são boas candidatas para particionamento. Uma prática comum é particionar os dados com base na hora, o que pode acarretar um esquema de particionamento em vários níveis.

O particionamento também tem um custo. Quando você aumenta o número de partições na tabela, o tempo necessário para recuperar e processar os metadados da partição também aumenta. Assim, o particionamento excessivo pode remover os benefícios obtidos ao particionar de forma mais criteriosa. Se os dados estiverem muito distorcidos para um valor de partição e a maioria das consultas usar esse valor, você poderá incorrer em aumento de sobrecarga.

Para obter mais informações sobre particionamento no Athena, consulte [O que é particionamento?](ctas-partitioning-and-bucketing-what-is-partitioning.md).

## Classificar dados em bucket
<a name="performance-tuning-s3-throttling-bucket-your-data"></a>

Outra forma de particionar dados é classificá-los em buckets dentro de uma única partição. Com o bucketing, você especifica uma ou mais colunas que contêm linhas que deseja agrupar. Em seguida, você coloca essas linhas em vários buckets. Dessa forma, você consulta somente o bucket que deve ser lido, reduzindo o número de linhas de dados que devem ser verificados.

Ao selecionar uma coluna que será usada para bucketing, selecione a coluna que tenha alta cardinalidade (ou seja, que tenha muitos valores distintos), esteja uniformemente distribuída e seja usada com frequência para filtrar os dados. Um exemplo de uma boa coluna a ser usada para bucketing é uma chave primária, como uma coluna de ID.

Para obter mais informações sobre bucketing no Athena, consulte [O que é bucketing?](ctas-partitioning-and-bucketing-what-is-bucketing.md)

## Usar índices de partição do AWS Glue
<a name="performance-tuning-s3-throttling-use-aws-glue-partition-indexes"></a>

Você pode usar índices de partição do AWS Glue para organizar dados em uma tabela com base nos valores de uma ou mais partições. Os índices de partição do AWS Glue podem reduzir o número de transferências de dados, a quantidade de processamento de dados e o tempo de processamento das consultas.

Um índice de partição do AWS Glue é um arquivo de metadados que contém informações sobre as partições da tabela, inclusive as chaves da partição e seus valores. O índice da partição é armazenado em um bucket do Amazon S3 e atualizado automaticamente pelo AWS Glue à medida que novas partições são adicionadas à tabela.

Quando há um índice de partição do AWS Glue presente, as consultas tentam buscar um subconjunto das partições em vez de carregar todas as partições na tabela. As consultas são executadas somente no subconjunto de dados relevante para a consulta.

Ao criar uma tabela no AWS Glue, é possível criar um índice de partição em qualquer combinação de chaves de partição definidas na tabela. Depois de criar um ou mais índices de partição em uma tabela, é necessário adicionar uma propriedade à tabela que habilite a filtragem de partições. Em seguida, você pode consultar a tabela no Athena.

Para obter informações sobre como criar índices de partição no AWS Glue, consulte [Trabalhar com índices de partição no AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html) no *Guia do desenvolvedor do AWS Glue*. Para obter informações sobre como adicionar uma propriedade de tabela para habilitar a filtragem de partições, consulte [Otimizar consultas com indexação e filtragem de partições do AWS Glue](glue-best-practices-partition-index.md).

## Usar compactação de dados e divisão de arquivos
<a name="performance-tuning-s3-throttling-use-data-compression-and-file-splitting"></a>

A compactação de dados pode acelerar consideravelmente as consultas se os arquivos estiverem no tamanho ideal ou se puderem ser divididos em grupos lógicos. Geralmente, taxas de compactação mais altas necessitam de mais ciclos de CPU para compactar e descompactar os dados. Para o Athena, recomendamos usar o Apache Parquet ou o Apache ORC, que compactam dados por padrão. Para obter mais informações sobre compactação de dados no Athena, consulte [Usar compactação no Athena](compression-formats.md).

A divisão de arquivos aumenta o paralelismo ao permitir que o Athena distribua a tarefa de ler um único arquivo entre vários leitores. Se um único arquivo não foi divisível, somente um único leitor poderá ler o arquivo enquanto outros leitores estiverem ociosos. O Apache Parquet e o Apache ORC também são compatíveis com arquivos divisíveis.

## Use armazenamentos de dados em colunas otimizados
<a name="performance-tuning-s3-throttling-use-optimized-columnar-data-stores"></a>

A performance da consulta do Athena melhorará consideravelmente se você converter os dados para um formato em colunas. Ao gerar arquivos em colunas, uma técnica de otimização a ser considerada é ordenar os dados com base na chave de partição.

O Apache Parquet e o Apache ORC são armazenamentos de dados em colunas de código aberto bastante usados. Para obter informações sobre como converter a fonte de dados existente do Amazon S3 para um desses formatos, consulte [Converter em formatos colunares](columnar-storage.md#convert-to-columnar).

### Usar um tamanho de bloco do Parquet ou tamanho de faixa ORC maior
<a name="performance-tuning-s3-throttling-use-a-larger-parquet-block-size-or-orc-stripe-size"></a>

O Parquet e o ORC têm parâmetros de armazenamento de dados que podem ser ajustados para otimização. No Parquet, é possível otimizar o tamanho do bloco. No ORC, é possível otimizar o tamanho da faixa. Quanto maior o bloco ou a faixa, mais linhas você poderá armazenar em cada um deles. Por padrão, o tamanho do bloco Parquet é 128 MB, e o tamanho da faixa ORC é 64 MB.

Se uma faixa ORC for menor que 8 MB (o valor padrão de `hive.orc.max_buffer_size`), o Athena lerá toda a faixa ORC. É a compensação que o Athena faz entre a seletividade da coluna e as operações de entrada e saída por segundo para faixas menores.

Se houver tabelas com um número muito grande de colunas, um tamanho pequeno de bloco ou de faixa pode fazer com que sejam verificados mais dados do que o necessário. Nesses casos, um tamanho maior de bloco pode ser mais eficiente.

### Usar ORC para tipos complexos
<a name="performance-tuning-s3-throttling-use-orc-for-complex-types"></a>

Atualmente, ao consultar colunas armazenadas em Parquet que tenham tipos de dados complexos (por exemplo, `array`, `map` ou `struct`), o Athena lê a linha de dados inteira em vez de somente as colunas especificadas seletivamente. Este é um problema conhecido do Athena. Como solução alternativa, considere usar o ORC.

### Escolher um algoritmo de compactação
<a name="performance-tuning-s3-throttling-choose-a-compression-algorithm"></a>

Outro parâmetro que pode ser configurado é o algoritmo de compactação nos blocos de dados. Para obter informações sobre os algoritmos de compactação compatíveis com Parquet e ORC no Athena, consulte [Suporte a compactação no Athena](https://docs.aws.amazon.com/athena/latest/ug/compression-formats.html).

Para obter mais informações sobre a otimização de formatos de armazenamento em colunas no Athena, consulte a seção “Otimizar a geração de armazenamento de dados em colunas” na publicação do AWS Big Data Blog [As dez melhores dicas de ajuste de performance para o Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/).

## Usar tabelas Iceberg
<a name="performance-tuning-s3-throttling-use-iceberg-tables"></a>

Apache Iceberg é um formato de tabela aberta para conjuntos de dados analíticos muito grandes, criado para otimizar o uso do Amazon S3. Você pode usar as tabelas Iceberg para ajudar a reduzir o controle de utilização no Amazon S3.

As tabelas Iceberg oferecem as seguintes vantagens:
+ É possível dividir as tabelas Iceberg em partições de uma ou mais colunas. Isso otimiza o acesso aos dados e reduz a quantidade de dados que deverão ser verificados por meio de consultas.
+ Como o modo de armazenamento de objetos do Iceberg otimiza as tabelas Iceberg para funcionar com o Amazon S3, ele pode processar grandes volumes de dados e workloads de consultas pesadas.
+ As tabelas Iceberg no modo de armazenamento de objetos são escaláveis, tolerantes a falhas e duráveis, o que pode ajudar a reduzir o controle de utilização.
+ Com o suporte à transação ACID, vários usuários podem adicionar e excluir objetos do Amazon S3 de forma atômica.

Para obter mais informações sobre o Apache Iceberg, consulte [Apache Iceberg](https://iceberg.apache.org/). Para obter mais informações sobre como usar tabelas Apache Iceberg no Athena, consulte [Usar tabelas Iceberg](https://docs.aws.amazon.com/athena/latest/ug/querying-iceberg.html).

# Otimizar suas consultas
<a name="performance-tuning-s3-throttling-optimizing-queries"></a>

Use as sugestões desta seção para otimizar as consultas SQL no Athena.

## Usar LIMIT com a cláusula ORDER BY
<a name="performance-tuning-s3-throttling-use-limit-with-the-order-by-clause"></a>

A cláusula `ORDER BY` retorna dados em uma ordem classificada. Isso exige que o Athena envie todas as linhas de dados para um único nó de processamento e classifique as linhas. Esse tipo de consulta pode ser executado por muito tempo ou pode até falhar.

Para aumentar a eficiência das consultas, observe os valores *N* superiores ou inferiores e use também uma cláusula `LIMIT`. Isso reduz significativamente o custo de classificação, inserindo tanto a classificação como a limitação em nós de processamento individuais, e não em um único operador.

## Otimizar cláusulas JOIN
<a name="performance-tuning-s3-throttling-optimize-join-clauses"></a>

Quando você une duas tabelas, o Athena distribui a tabela à direita para os nós de processamento e transmite a tabela à esquerda para realizar a junção.

Por isso, especifique a tabela maior no lado esquerdo da junção e a tabela menor no lado direito da junção. Assim, o Athena usa menos memória e executa a consulta com menor latência.

Observe também os seguintes pontos:
+ Ao usar vários comandos `JOIN`, especifique as tabelas da maior para a menor.
+ Evite junções cruzadas, a menos que sejam exigidas pela consulta.

## Otimizar cláusulas GROUP BY
<a name="performance-tuning-s3-throttling-optimize-group-by-clauses"></a>

O operador `GROUP BY` distribui as linhas com base nas colunas `GROUP BY` para os nós de processamento. Essas colunas são referenciadas na memória, e os valores são comparados à medida que as linhas são ingeridas. Os valores são agregados quando a coluna `GROUP BY` coincide. Considerando a forma como o processo funciona, é aconselhável ordenar as colunas da maior cardinalidade para a menor.

## Usar números em vez de strings
<a name="performance-tuning-s3-throttling-use-numbers-instead-of-strings"></a>

Como os números exigem menos memória e são mais rápidos de processar em comparação com as strings, use números em vez de strings quando possível.

## Limitar o número de colunas
<a name="performance-tuning-s3-throttling-limit-the-number-of-columns"></a>

Para reduzir a quantidade total de memória necessária para armazenar os dados, limite o número de colunas especificado na instrução `SELECT`.

## Usar expressões regulares em vez de LIKE
<a name="performance-tuning-s3-throttling-use-regular-expressions-instead-of-like"></a>

Consultas que incluem cláusulas como `LIKE '%string%'` em strings grandes podem fazer uso muito intensivo de computação. Ao filtrar por vários valores em uma coluna de string, use a função [regexp\$1like()](https://trino.io/docs/current/functions/regexp.html#regexp_like) e uma expressão regular. Isso é útil especialmente ao comparar uma longa lista de valores.

## Usar a cláusula LIMIT
<a name="performance-tuning-s3-throttling-use-the-limit-clause"></a>

Em vez de selecionar todas as colunas ao executar uma consulta, use a cláusula `LIMIT` para retornar somente as colunas necessárias. Essa ação reduz o tamanho do conjunto de dados que é processado pelo pipeline de execução da consulta. As cláusulas `LIMIT` são mais úteis ao consultar tabelas que têm um grande número de colunas baseadas em strings. As cláusulas `LIMIT` também são úteis ao executar várias junções ou agregações em qualquer consulta.

# Recursos adicionais
<a name="performance-tuning-additional-resources"></a>

Para obter mais informações sobre ajuste de performance no Athena, acesse estes recursos:
+ Publicação no Blog de Big Data da AWS: [As 10 melhores dicas de ajuste de performance do Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/).
+ Publicação no Blog de Big Data da AWS: [Executa consultas 3 vezes mais rápido e com até 70% de economia de custos no mecanismo mais recente do Amazon Athena](https://aws.amazon.com/blogs/big-data/run-queries-3x-faster-with-up-to-70-cost-savings-on-the-latest-amazon-athena-engine/) no *Blog de Big Data da AWS*.
+ Publicação no Blog de Big Data da AWS: [Aprimorar consultas federadas com a redução de predicados no Amazon Athena](https://aws.amazon.com/blogs/big-data/improve-federated-queries-with-predicate-pushdown-in-amazon-athena/).
+ Guia do usuário do Amazon Simple Storage Service: [Práticas recomendadas de padrões de design: otimização da performance do Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html).
+ Outras [publicações do Athena no Blog de Big Data da AWS](https://aws.amazon.com/blogs/big-data/tag/amazon-athena/) 
+ Faça uma pergunta no [AWS re:Post](https://repost.aws/tags/TA78iVOM7gR62_QqDe2-CmiA/amazon-athena) usando a tag **Amazon Athena**
+ Consulte os [tópicos do Athena na Central de Conhecimento da AWS](https://aws.amazon.com/premiumsupport/knowledge-center/#Amazon_Athena)
+ Entre em contato com AWS Support (no Console de gerenciamento da AWS, clique em **Support** (Suporte), **Support Center** (Central de Suporte))