

# Solucionar problemas de performance em bancos de dados do Aurora MySQL
<a name="aurora-mysql-troubleshooting-query"></a>

O MySQL fornece [controle do otimizador de consultas](https://dev.mysql.com/doc/refman/8.0/en/controlling-optimizer.html) por meio de variáveis do sistema que afetam a forma como os planos de consulta são avaliados, otimizações selecionáveis, dicas de otimizador e índice e o modelo de custo do otimizador. Esses pontos de dados podem ser úteis não apenas para comparar diferentes ambientes do MySQL, mas também para comparar planos de execução de consultas anteriores com planos de execução atuais e para entender a execução geral de uma consulta do MySQL a qualquer momento.

O desempenho da consulta depende de muitos fatores, incluindo o plano de execução, o esquema e o tamanho da tabela, estatísticas, recursos, índices e configuração de parâmetros. O ajuste de consultas requer a identificação de gargalos e a otimização do caminho de execução.
+ Encontre o plano de execução da consulta e verifique se ela está usando índices apropriados. É possível otimizar a consulta usando `EXPLAIN` e revisando os detalhes de cada plano.
+ O Aurora MySQL versão 3 (compatível com o MySQL 8.0 Community Edition) usa uma instrução `EXPLAIN ANALYZE`. A instrução `EXPLAIN ANALYZE` é uma ferramenta de criação de perfil que mostra onde o MySQL gasta tempo na consulta e por quê. Com `EXPLAIN ANALYZE`, o Aurora MySQL planeja, prepara e executa a consulta enquanto conta as linhas e mede o tempo gasto em vários pontos do plano de execução. Quando a consulta é concluída, `EXPLAIN ANALYZE` imprime o plano e suas medições em vez do resultado da consulta.
+ Mantenha as estatísticas do esquema atualizadas usando a instrução `ANALYZE`. Às vezes, o otimizador de consultas pode escolher planos de execução inadequados devido a estatísticas desatualizadas. Isso pode levar a um desempenho insatisfatório de uma consulta devido às estimativas de cardinalidade imprecisas das tabelas e dos índices. A coluna `last_update` da tabela [innodb\_table\_stats](https://dev.mysql.com/doc/refman/8.0/en/innodb-persistent-stats.html#innodb-persistent-stats-tables) mostra a última vez que as estatísticas do esquema foram atualizadas, o que é um bom indicador de “desatualização”.
+ Outros problemas podem ocorrer, como distorção da distribuição de dados, que não são levados em consideração para a cardinalidade da tabela. Consulte mais informações em [Estimating ANALYZE TABLE complexity for InnoDB tables](https://dev.mysql.com/doc/refman/8.0/en/innodb-analyze-table-complexity.html) e [Histogram statistics in MySQL](https://dev.mysql.com/blog-archive/histogram-statistics-in-mysql/) na documentação do MySQL.

## Noções básicas do tempo gasto com consultas
<a name="ams-query-time"></a>

Veja a seguir formas de determinar o tempo gasto pelas consultas:
+ [Criação de perfil](https://dev.mysql.com/doc/refman/8.0/en/show-profile.html)
+ [Esquema de desempenho](https://dev.mysql.com/doc/refman/8.0/en/performance-schema.html)
+ [Otimizador de consultas](https://dev.mysql.com/doc/refman/8.0/en/controlling-optimizer.html)

**Criação de perfil**  
Por padrão, a criação de perfil está desabilitada. Habilite a criação de perfil, depois execute a consulta lenta e revise seu perfil.  

```
SET profiling = 1;
{{Run your query.}}
SHOW PROFILE;
```

1. Identifique o estágio em que a maior parte do tempo é gasto. De acordo com [General thread states](https://dev.mysql.com/doc/refman/8.0/en/general-thread-states.html) na documentação do MySQL, ler e processar linhas de uma instrução `SELECT` geralmente é o estado de execução mais longa durante a vida útil de uma determinada consulta. É possível usar a instrução `EXPLAIN` para entender como o MySQL executa essa consulta.

1. Analise o log de consultas lentas para avaliar `rows_examined` e `rows_sent` a fim de garantir que a workload seja semelhante em cada ambiente. Para obter mais informações, consulte [Registro em log de bancos de dados do Aurora MySQL](aurora-mysql-troubleshooting-logging.md).

1. Execute o comando a seguir para tabelas que fazem parte da consulta identificada:

   ```
   SHOW TABLE STATUS\G;
   ```

1. Capture as seguintes saídas antes e depois de executar a consulta em cada ambiente:

   ```
   SHOW GLOBAL STATUS;
   ```

1. Execute os comandos a seguir em cada ambiente para ver se há alguma outra consulta/sessão influenciando o desempenho dessa consulta de amostra.

   ```
   SHOW FULL PROCESSLIST;
   
   SHOW ENGINE INNODB STATUS\G;
   ```

   Às vezes, quando os recursos no servidor estão ocupados, isso afeta todas as outras operações no servidor, incluindo consultas. Também é possível capturar informações periodicamente quando as consultas são executadas ou configurar um trabalho `cron` para capturar informações em intervalos úteis.

**Performance Schema**  
O Performance Schema fornece informações úteis sobre o desempenho do tempo de execução do servidor, embora tenha um impacto mínimo sobre esse desempenho. Isso é diferente de `information_schema`, que fornece informações de esquema sobre a instância de banco de dados. Para obter mais informações, consulte [Visão geral do Performance Schema para o Insights de Performance no Aurora MySQL](USER_PerfInsights.EnableMySQL.md).

**Rastreamento do otimizador de consulta**  
Para entender por que um [plano de consulta específico foi escolhido para execução](https://dev.mysql.com/doc/refman/8.0/en/execution-plan-information.html), é possível configurar `optimizer_trace` para acessar o otimizador de consultas do MySQL.  
Execute um rastreamento do otimizador para mostrar informações abrangentes sobre todos os caminhos disponíveis para o otimizador e sua escolha.  

```
SET SESSION OPTIMIZER_TRACE="enabled=on"; 
SET optimizer_trace_offset=-5, optimizer_trace_limit=5;

-- Run your query.
SELECT * FROM table WHERE x = 1 AND y = 'A';

-- After the query completes:
SELECT * FROM information_schema.OPTIMIZER_TRACE;
SET SESSION OPTIMIZER_TRACE="enabled=off";
```

## Revisar as configurações do otimizador de consultas
<a name="ams-query-parameters"></a>

O Aurora MySQL versão 3 (compatível com MySQL 8.0 Community Edition) tem muitas alterações relacionadas ao otimizador em comparação com o Aurora MySQL versão 2 (compatível com o MySQL 5.7 Community Edition). Se você tiver alguns valores personalizados para `optimizer_switch`, recomendamos que analise as diferenças nos padrões e defina os valores de `optimizer_switch` que funcionem melhor para sua workload. Também recomendamos que você teste as opções disponíveis para o Aurora MySQL versão 3 para examinar o desempenho das consultas.

**nota**  
O Aurora MySQL versão 3 usa o valor padrão da comunidade de 20 para o parâmetro [innodb\_stats\_persistent\_sample\_pages](https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_stats_persistent_sample_pages).

É possível usar o seguinte comando para mostrar os valores de `optimizer_switch`:

```
SELECT @@optimizer_switch\G;
```

A tabela a seguir mostra os valores padrão de `optimizer_switch` do Aurora MySQL versões 2 e 3.


| Configuração | Aurora MySQL versão 2 | Aurora MySQL versão 3 | 
| --- | --- | --- | 
| batched\_key\_access | desligar | desligar | 
| block\_nested\_loop | ativado | ativado | 
| condition\_fanout\_filter | ativado | ativado | 
| derived\_condition\_pushdown | – | ativado | 
| derived\_merge | ativado | ativado | 
| duplicateweedout | ativado | ativado | 
| engine\_condition\_pushdown | ativado | ativado | 
| firstmatch | ativado | ativado | 
| hash\_join | desligar | ativado | 
| hash\_join\_cost\_based | ativado | – | 
| hypergraph\_optimizer | – | desligar | 
| index\_condition\_pushdown | ativado | ativado | 
| index\_merge | ativado | ativado | 
| index\_merge\_intersection | ativado | ativado | 
| index\_merge\_sort\_union | ativado | ativado | 
| index\_merge\_union | ativado | ativado | 
| loosescan | ativado | ativado | 
| materialization | ativado | ativado | 
| mrr | ativado | ativado | 
| mrr\_cost\_based | ativado | ativado | 
| prefer\_ordering\_index | ativado | ativado | 
| semijoin | ativado | ativado | 
| skip\_scan | – | ativado | 
| subquery\_materialization\_cost\_based | ativado | ativado | 
| subquery\_to\_derived | – | desligar | 
| use\_index\_extensions | ativado | ativado | 
| use\_invisible\_indexes | – | desligar | 

Consulte mais informações em [Switchable optimizations (MySQL 5.7)](https://dev.mysql.com/doc/refman/5.7/en/switchable-optimizations.html) e [Switchable optimizations (MySQL 8.0)](https://dev.mysql.com/doc/refman/8.0/en/switchable-optimizations.html) na documentação do MySQL.