Práticas recomendadas para consultas paralelas no RDS para PostgreSQL - Amazon Relational Database Service

Práticas recomendadas para consultas paralelas no RDS para PostgreSQL

A execução de consultas paralelas é um recurso do PostgreSQL que permite que uma única consulta SQL seja dividida em tarefas menores que são realizadas simultaneamente por vários processos de operador em segundo plano. Em vez de executar uma consulta inteiramente em um único processo de backend, o PostgreSQL pode distribuir partes da consulta, como verificações, junções, agregações ou classificações, em vários núcleos de CPU. O processo líder coordena essa execução e reúne os resultados dos operadores paralelos.

No entanto, para a maioria das workloads de produção, especialmente sistemas de processamento de transações on-line (OLTP) com alta simultaneidade, recomendamos desabilitar a execução automática de consultas paralelas. Embora o paralelismo possa acelerar as consultas em grandes conjuntos de dados em workloads de analytics ou geração de relatórios, ele apresenta riscos significativos que geralmente superam os benefícios em ambientes de produção movimentados.

A execução paralela também gera custos indiretos significativos. Cada operador paralelo é um processo completo de backend no PostgreSQL, que requer bifurcação (cópia de estruturas de memória e inicialização do estado do processo) e autenticação de processos (consumo de slots de conexão do limite de max_connections). Cada operador também consome sua própria memória, inclusive work_mem para operações de classificação e hash. Quando há vários operadores por consulta, o uso da memória se multiplica rapidamente (p. ex., 4 operadores × 64 MB de work_mem = 256 MB por consulta). Por isso, as consultas paralelas podem consumir consideravelmente mais recursos do sistema do que as consultas de processo único. Se elas não forem ajustadas adequadamente, poderá haver saturação da CPU (vários operadores consomem a capacidade de processamento disponível), aumento da troca de contexto (o sistema operacional alterna frequentemente entre vários processos de operador, aumentando os custos indiretos e reduzindo o throughput) ou exaustão da conexão (visto que cada operador paralelo consome um slot de conexão, uma única consulta com quatro operadores usa cinco conexões no total, uma líder + quatro operadores, o que pode esgotar rapidamente o grupo de conexões quando há alta simultaneidade, impedindo novas conexões de cliente e causando falhas na aplicação). Esses problemas são particularmente graves em workloads com alta simultaneidade, nas quais várias consultas podem tentar a execução paralela simultaneamente.

O PostgreSQL decide se deve usar o paralelismo com base em estimativas de custo. Em alguns casos, o planejador pode mudar automaticamente para um plano paralelo se isso parecer mais barato, mesmo quando não for o ideal na prática. Isso pode ocorrer se as estatísticas do índice estiverem desatualizadas ou se o inchaço fizer com que as verificações sequenciais pareçam mais atrativas do que as pesquisas de índice. Devido a esse comportamento, os planos paralelos automáticos às vezes podem provocar regressões no desempenho da consulta ou na estabilidade do sistema.

Para extrair o máximo benefício das consultas paralelas no RDS para PostgreSQL, é importante testá-las e ajustá-las com base na workload, monitorar o impacto sobre o sistema e desabilitar a seleção automática de planos paralelos em favor do controle em nível de consulta.

Parâmetros de configuração

O PostgreSQL usa vários parâmetros para controlar o comportamento e a disponibilidade de consultas paralelas. Compreendê-los e ajustá-los é fundamental para alcançar um desempenho previsível:

Parâmetro Descrição Padrão
max_parallel_workers Número máximo de processos de operador em segundo plano que podem ser executados no total. GREATEST($DBInstanceVCPU/2,8)
max_parallel_workers_per_gather Número máximo de operadores por nó do plano de consulta (p. ex., por Gather). 2
parallel_setup_cost Custo adicional do planejador para iniciar a infraestrutura de consulta paralela. 1.000
parallel_tuple_cost Custo por tupla processada em modo paralelo (afeta a decisão do planejador). 0,1
force_parallel_mode Força o planejador a testar planos paralelos (off, on, regress). off

Considerações importantes

  • max_parallel_workers controla o conjunto total de operadores paralelos. Se definido com um valor muito baixo, algumas consultas podem voltar à execução em série.

  • max_parallel_workers_per_gather determina quantos operadores uma única consulta pode usar. Um valor maior aumenta a simultaneidade, mas também o uso de recursos.

  • parallel_setup_cost e parallel_tuple_cost afetam o modelo de custo do planejador. Reduzi-los pode aumentar a probabilidade de os planos paralelos serem escolhidos.

  • force_parallel_mode é útil para testes, mas não deve ser usado na produção, a menos que necessário.

nota

O valor padrão do max_parallel_workers parâmetro é calculado dinamicamente com base no tamanho da instância usando a fórmulaGREATEST($DBInstanceVCPU/2, 8). Isso significa que quando você escalar a computação de uma instância de banco de dados para um tamanho maior com mais vCPUs, o número máximo de operadores paralelos disponíveis aumentará automaticamente. Por isso, consultas que antes eram executadas em série ou com paralelismo limitado podem utilizar mais operadores paralelos de maneira repentina após uma operação de aumento da escala vertical e possivelmente provocar aumentos inesperados no uso da conexão, na utilização da CPU e no consumo de memória. É importante monitorar o comportamento da consulta paralela após qualquer evento de ajuste de escala da computação e, se necessário, ajustar max_parallel_workers_per_gather para manter o uso previsível dos recursos.

Identificar o uso de consultas paralelas

As consultas podem mudar para planos paralelos com base na distribuição de dados ou nas estatísticas. Por exemplo:

SELECT count(*) FROM customers WHERE last_login < now() - interval '6 months';

Essa consulta pode usar um índice para dados recentes, mas mudar para uma verificação sequencial paralela de dados históricos.

É possível registrar em log os planos de execução de consultas carregando o módulo auto_explain. Para saber mais, consulte Como registrar em log planos de execução de consultas no Centro de Conhecimento da AWS.

É possível monitorar eventos de espera no CloudWatch Database Insights relacionados à consulta paralela. Para saber mais sobre eventos de espera relacionados à consulta paralela, consulte IPC: eventos de espera paralelos.

A partir da versão 18 do PostgreSQL, é possível monitorar a atividade de operadores paralelos usando novas colunas em pg_stat_database e pg_stat_statements:

  • parallel_workers_to_launch: número de operadores paralelos que se pretende iniciar.

  • parallel_workers_launched: número de operadores paralelos realmente iniciados.

Essas métricas ajudam a identificar discrepâncias entre o paralelismo planejado e real, o que pode indicar restrições de recursos ou problemas de configuração. Use as seguintes consultas para monitorar a execução paralela:

Para métricas de operadores paralelos em nível de banco de dados:

SELECT datname, parallel_workers_to_launch, parallel_workers_launched FROM pg_stat_database WHERE datname = current_database();

Para métricas de operadores paralelos em nível de consulta:

SELECT query, parallel_workers_to_launch, parallel_workers_launched FROM pg_stat_statements ORDER BY parallel_workers_launched;

Como controlar o paralelismo

Há várias maneiras de controlar o paralelismo de consultas, cada uma projetada para diferentes cenários e requisitos.

Para desabilitar o paralelismo automático globalmente, modifique seu grupo de parâmetros para definir:

max_parallel_workers_per_gather = 0;

Para configurações persistentes e específicas do usuário, o comando ALTER ROLE oferece uma maneira para definir parâmetros que se aplicarão a todas as sessões futuras de determinado usuário.

Por exemplo:

ALTER ROLE username SET max_parallel_workers_per_gather = 4; garante que, toda vez que esse usuário se conectar ao banco de dados, as respectivas sessões usarão essa configuração de operador paralelo quando necessário.

O controle em nível de sessão pode ser obtido usando o comando SET, que modifica os parâmetros durante a sessão atual do banco de dados. Isso é particularmente útil quando é necessário ajustar temporariamente as configurações sem afetar outros usuários ou sessões futuras. Depois de definidos, esses parâmetros permanecem em vigor até serem redefinidos explicitamente ou até que a sessão termine. Os comandos são simples:

SET max_parallel_workers_per_gather = 4; -- Run your queries RESET max_parallel_workers_per_gather;

Para ter um controle ainda mais granular, o SET LOCAL permite modificar os parâmetros de uma única transação. Isso é ideal quando é necessário ajustar as configurações de um conjunto específico de consultas em uma transação e, após isso, reverter automaticamente as configurações para os valores anteriores. Essa abordagem ajuda a evitar efeitos indesejados em outras operações na mesma sessão.

Diagnosticar o comportamento das consultas paralelas

Use EXPLAIN (ANALYZE, VERBOSE) para confirmar se uma consulta usou execução paralela:

  • Procure nós como Gather, Gather Merge ou Parallel Seq Scan.

  • Compare os planos com e sem paralelismo.

Para desabilitar temporariamente o paralelismo para comparação:

SET max_parallel_workers_per_gather = 0; EXPLAIN ANALYZE <your_query>; RESET max_parallel_workers_per_gather;