19.7. Planejamento de consulta #

19.7.1. Configuração do método do planejador
19.7.2. Constantes de custo do planejador
19.7.3. Otimizador de consultas genético
19.7.4. Outras opções do planejador

19.7.1. Configuração do método do planejador #

Estes parâmetros de configuração fornecem um método rudimentar de influenciar os planos de consulta escolhidos pelo otimizador de consultas. Se o plano padrão escolhido pelo otimizador para uma determinada consulta não for o ideal, uma solução temporária é usar um desses parâmetros de configuração para forçar o otimizador a escolher um plano diferente. As melhores maneiras de melhorar a qualidade dos planos escolhidos pelo otimizador incluem ajustar as constantes de custo do planejador (veja Constantes de custo do planejador), executar o comando ANALYZE manualmente, aumentar o valor do parâmetro de configuração default_statistics_target, e aumentar a quantidade de estatísticas coletadas para colunas específicas usando ALTER TABLE SET STATISTICS.

enable_async_append (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Asynchronous Append (que levam em conta a natureza assíncrona das adições). O padrão é on.

enable_bitmapscan (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Bitmap Scan (varredura de bitmap). O padrão é on.

enable_distinct_reordering (boolean) #

Ativa ou desativa capacidade do planejador de consultas de reordenar as chaves DISTINCT para corresponder às chaves de caminho (pathkeys) do caminho de entrada. O padrão é on.

enable_gathermerge (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Gather Merge (que combina a saída de nós filhos, executados por processos trabalhadores paralelos). O padrão é on.

enable_group_by_reordering (boolean) #

Controla se o planejador de consultas irá produzir um plano que forneça chaves GROUP BY ordenadas segundo as chaves de um nó filho do plano, como uma varredura de índice. Quando inativo, o planejador de consultas irá produzir um plano com as chaves do GROUP BY ordenadas apenas para corresponder à cláusula ORDER BY, se houver. Quando ativo, o planejador tentará produzir um plano mais eficiente. O padrão é on.

enable_hashagg (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano HashAggregate (agregação por hash). O padrão é on.

enable_hashjoin (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Hash Join (junção por hash). O padrão é on.

enable_incremental_sort (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Incremental Sort (etapas de classificação incrementais). O padrão é on.

enable_indexscan (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Index Scan (varredura de índice) e Index Only Scan (varredura apenas de índice). O padrão é on. Veja também enable_indexonlyscan.

enable_indexonlyscan (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Index Only Scan (varredura somente de índice) (veja Varreduras somente de índice e índices de cobertura). O padrão é on. A configuração enable_indexscan também deve estar ativa para que o planejador de consultas considere varreduras apenas de índice.

enable_material (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Materialize (materialização). É impossível suprimir inteiramente a materialização, mas desativar esta variável impede que o planejador insira nós de materialização, exceto nos casos em que é necessário para correção. O padrão é on.

enable_memoize (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Memoize (memorizar), que armazena em cache os resultados de varreduras parametrizadas dentro de junções de laço aninhado. Este tipo de plano permite que as varreduras para os planos subjacentes sejam ignoradas quando os resultados dos parâmetros correntes já estiverem no cache. Os resultados procurados com menos frequência podem ser removidos do cache quando houver necessidade de mais espaço para novas entradas. O padrão é on.

enable_mergejoin (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Merge Join (junção por mesclagem). O padrão é on.

enable_nestloop (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Nested Loop (laço aninhado). É impossível suprimir inteiramente as junções de laço aninhado, mas desativar esta variável desencoraja o planejador de usá-las se houver outros métodos disponíveis. O padrão é on.

enable_parallel_append (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Append com paralelismo. O padrão é on.

enable_parallel_hash (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Hash Join com paralelismo. Não tem efeito se os planos de junção por hash também não estiverem ativos. O padrão é on.

enable_partition_pruning (boolean) #

Ativa ou desativa a capacidade do planejador de consultas de eliminar as partições de uma tabela particionada dos planos de consulta. Também controla a capacidade do planejador de gerar planos de consulta que permitem ao executor da consulta remover (ignorar) partições durante a execução da consulta. O padrão é on. Veja Remoção de partição para obter detalhes.

enable_partitionwise_join (boolean) #

Ativa ou desativa o uso pelo planejador de consultas de junção por partição, que permite que uma junção entre tabelas particionadas seja executada juntando as partições correspondentes. No momento, a junção particionada aplica-se apenas quando as condições de junção incluem todas as chaves da partição, que devem ser do mesmo tipo de dados, e ter conjuntos correspondentes de um para um de partições filhas. Com esta configuração ativa, o número de nós que aparecem no plano final e cujo uso de memória é restringido por work_mem pode aumentar linearmente de conforme o número de partições sendo varridas. Isto pode resultar em um grande aumento no consumo geral de memória durante a execução da consulta. O planejamento de consultas também se torna significativamente mais custoso em termos de memória e CPU. O padrão é off.

enable_partitionwise_aggregate (boolean) #

Ativa ou desativa o uso pelo planejador de consultas do agrupamento ou agregação por partição (partitionwise), permitindo que o agrupamento ou a agregação em tabelas particionadas sejam realizados separadamente para cada partição. Se a cláusula GROUP BY não incluir as chaves de partição, poderá ser realizada apenas uma agregação parcial por partição, e a finalização deverá ser feita posteriormente. Com esta configuração ativa, o número de nós no plano final cujo uso de memória é restringido por work_mem pode aumentar linearmente conforme o número de partições sendo varridas. Isto pode resultar em um grande aumento no consumo geral de memória durante a execução da consulta. O planejamento de consultas também se torna significativamente mais custoso em termos de memória e CPU. O padrão é off.

enable_presorted_aggregate (boolean) #

Controla se o planejador de consultas irá produzir um plano que forneça linhas pré-ordenadas na ordem exigida para as funções de agregação ORDER BY / DISTINCT da consulta. Quando inativo, o planejador de consultas irá produzir um plano que sempre exigirá que o executor realize uma ordenação antes de efetuar a agregação de cada função de agregação que contenha uma cláusula ORDER BY ou DISTINCT. Quando ativo, o planejador tentará produzir um plano mais eficiente que forneça às funções de agregação dados pré-ordenados na ordem exigida para a agregação. O padrão é on.

enable_self_join_elimination (boolean) #

Ativa ou desativa a otimização do planejador de consultas que analisa a árvore de consulta e substitui auto-junções por varreduras únicas semanticamente equivalentes. Leva em consideração apenas tabelas simples. O padrão é on.

enable_seqscan (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Seq Scan (varredura sequencial). É impossível suprimir inteiramente as varreduras sequenciais, mas desativar esta variável desencoraja o planejador de usá-las se houver outros métodos disponíveis. O padrão é on.

enable_sort (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Sort (etapas de classificação explícitas). É impossível suprimir inteiramente as classificações explícitas, mas desativar esta variável desencoraja o planejador de usá-las se houver outros métodos disponíveis. O padrão é on.

enable_tidscan (boolean) #

Ativa ou desativa o uso pelo planejador de consultas dos tipos de plano Tid Scan O padrão é on.

19.7.2. Constantes de custo do planejador #

As variáveis de custo descritas nesta seção são medidas em uma escala arbitrária. Apenas seus valores relativos importam, portanto, ajustá-los todos para cima ou para baixo pelo mesmo fator resultará em nenhuma mudança nas escolhas do planejador. Por padrão, estas variáveis de custo são baseadas no custo de buscas de páginas sequenciais; ou seja, seq_page_cost é definido convencionalmente como 1.0, e as outras variáveis de custo são definidas com referência a ele. Mas pode-se usar uma escala diferente se preferir, como tempos de execução reais em milissegundos em uma máquina específica.

Nota

Infelizmente não existe um método bem definido para determinar os valores ideais para as variáveis de custo. Eles são melhor tratados como médias de toda a combinação de consultas que uma instalação específica irá receber. Isto significa que os alterar com base em apenas alguns experimentos é muito arriscado.

seq_page_cost (floating point) #

Define a estimativa do planejador do custo de uma busca de página de disco que faz parte de uma série de buscas sequenciais. O padrão é 1.0. Este valor pode ser sobreposto para tabelas e índices em um espaço de tabelas específico, definindo o parâmetro de mesmo nome para o espaço de tabelas (veja ALTER TABLESPACE).

random_page_cost (floating point) #

Define a estimativa do planejador do custo de uma página de disco buscada não sequencialmente. O padrão é 4.0. Este valor pode ser substituído para tabelas e índices em um espaço de tabelas específico, definindo o parâmetro de mesmo nome para o espaço de tabelas (veja ALTER TABLESPACE).

Reduzir este valor com relação a seq_page_cost fará com que o sistema dê preferência a varreduras de índice; aumentá-lo fará com que as varreduras de índice pareçam relativamente mais caras. Pode-se aumentar ou diminuir os dois valores juntos para alterar a importância dos custos de E/S de disco em relação aos custos de CPU, descritos pelos parâmetros a seguir.

O acesso aleatório a armazenamento persistente é, normalmente, muito mais custoso do que quatro vezes o acesso sequencial. Entretanto, utiliza-se um valor padrão mais baixo (4.0), porque se pressupõe que a maioria dos acessos aleatórios ao armazenamento — como leituras indexadas — esteja em cache. Além disso, a latência do armazenamento conectado à rede tende a reduzir a sobrecarga relativa do acesso aleatório.

Caso se acredite que o cache ocorre com menos frequência do que o valor padrão reflete, e que a latência de rede é mínima, pode-se aumentar o random_page_cost para refletir melhor o custo real de leituras aleatórias de armazenamento. Os armazenamentos que apresentam um custo de leitura aleatória mais elevado em relação à leitura sequencial, como discos magnéticos, também podem ser melhor modelados com um valor mais alto para random_page_cost. Da mesma forma, se for provável que os dados estejam inteiramente em cache — como quando o banco de dados é menor do que a memória total do servidor, ou a latência da rede é alta —, pode ser apropriado reduzir random_page_cost.

Dica

Embora o sistema permita que se defina o parâmetro random_page_cost inferior a seq_page_cost, não é fisicamente sensato fazer isto. Entretanto, defini-los iguais faz sentido se o banco de dados for inteiramente armazenado em cache na RAM, porque neste caso não há penalidade por tocar em páginas fora de sequência. Além disso, em um banco de dados com muito cache, deve-se diminuir os dois valores relativos aos parâmetros de CPU, porque o custo de buscar uma página que já está na RAM é muito menor do que seria se não estivesse.

cpu_tuple_cost (floating point) #

Define a estimativa do planejador do custo de processamento de cada linha durante uma consulta. O padrão é 0.01.

cpu_index_tuple_cost (floating point) #

Define a estimativa do planejador do custo de processamento de cada entrada do índice durante uma varredura de índice. O padrão é 0.005.

cpu_operator_cost (floating point) #

Define a estimativa do planejador do custo de processamento de cada operador ou função executada durante uma consulta. O padrão é 0.0025.

parallel_setup_cost (floating point) #

Define a estimativa do planejador do custo de ativação de processos trabalhadores paralelos. O padrão é 1000.

parallel_tuple_cost (floating point) #

Define a estimativa do planejador do custo de transferência de uma tupla de um processo trabalhador paralelo para outro processo. O padrão é 0.1.

min_parallel_table_scan_size (integer) #

Define a quantidade mínima de dados da tabela que devem ser varridos para que a varredura paralela seja considerada. Para uma varredura sequencial paralela, a quantidade de dados da tabela varridos é sempre igual ao tamanho da tabela, mas quando são usados índices, a quantidade de dados da tabela varridos será normalmente menor. Se o valor for especificado sem unidade, será considerado sendo blocos, ou seja, BLCKSZ bytes, normalmente 8kB. O padrão é 8 megabytes (8MB).

min_parallel_index_scan_size (integer) #

Define a quantidade mínima de dados de índice que deve ser examinada para que um exame paralelo seja considerado. Note-se que uma varredura paralela de índice normalmente não percorre o índice inteiro; o importante é o número de páginas que o planejador acredita que serão efetivamente acessadas pela varredura. Este parâmetro também é utilizado para decidir se um determinado índice pode participar de uma limpeza em paralelo. Veja VACUUM. Se o valor for especificado sem unidade, será considerado sendo blocos, ou seja, BLCKSZ bytes, normalmente 8kB. O padrão é 512 kilobytes (512kB).

effective_cache_size (integer) #

Define a suposição do planejador sobre o tamanho efetivo do cache de disco que está disponível para uma única consulta. É levado em consideração nas estimativas do custo do uso de um índice; um valor mais alto aumenta a probabilidade de que sejam usadas varreduras de índice, um valor mais baixo aumenta a probabilidade de que sejam usadas varreduras sequenciais. Ao definir este parâmetro, deve-se considerar os buffers compartilhados do PostgreSQL, e a parte do cache de disco do kernel que será usado para os arquivos de dados do PostgreSQL, embora alguns dados possam existir nos dois lugares. Além disso, deve-se levar em consideração o número esperado de consultas simultâneas em tabelas diferentes, porque elas terão que compartilhar o espaço disponível. Este parâmetro não tem efeito sobre o tamanho da memória compartilhada alocada pelo PostgreSQL, nem reserva o cache de disco do kernel; é usado apenas para fins de estimativa. O sistema também não assume que os dados permanecem no cache de disco entre as consultas. Se o valor for especificado sem unidade, será considerado sendo blocos, ou seja, BLCKSZ bytes, normalmente 8kB. O padrão é 4 gigabytes (4GB). (Se BLCKSZ não for 8kB, o valor padrão será dimensionado proporcionalmente a ele.)

jit_above_cost (floating point) #

Define o custo da consulta acima do qual a compilação JIT é acionada, se estiver ativa (veja Compilação Just-in-Time (JIT)). Executar a compilação JIT custa tempo de planejamento, mas pode acelerar a execução da consulta. Definir como -1 desativa a compilação JIT. O padrão é 100000.

jit_inline_above_cost (floating point) #

Define o custo da consulta acima do qual a compilação JIT tenta incorporar funções e operadores. A incorporação adiciona tempo de planejamento, mas pode melhorar a velocidade de execução. Não faz sentido definir como menor que o parâmetro jit_above_cost. Definir como -1 desativa a incorporação. O padrão é 500000.

jit_optimize_above_cost (floating point) #

Define o custo da consulta acima do qual a compilação JIT aplica otimizações caras. Esta otimização aumenta o tempo de planejamento, mas pode melhorar a velocidade de execução. Não faz sentido defini-lo com um valor inferior ao do parâmetro jit_above_cost, sendo pouco provável que seja benéfico defini-lo com um valor superior ao do parâmetro jit_inline_above_cost. Definir como -1 desativa as otimizações caras. O padrão é 500000.

19.7.3. Otimizador de consultas genético #

O Otimizador de consultas genético (Genetic Query Optimizer / GEQO) é um algoritmo que planeja consulta usando procura heurística. Isto reduz o tempo de planejamento de consultas complexas (aquelas que reúnem muitas relações), ao custo de produzir planos às vezes inferiores aos encontrados pelo algoritmo normal de busca exaustiva.

geqo (boolean) #

Ativa ou desativa o otimizador de consulta genético. Está ativo por padrão. Geralmente é melhor não o desativar em produção; a variável geqo_threshold fornece um controle mais granular do GEQO.

geqo_threshold (integer) #

Usa o otimizador de consulta genético para planejar consultas com pelo menos esta quantidade de itens FROM envolvidos. (Note-se que uma construção FULL OUTER JOIN conta como apenas um item FROM.) O padrão é 12. Para consultas mais simples, é geralmente melhor usar o planejador regular de procura exaustiva, mas para consultas com muitas tabelas, a procura exaustiva leva muito tempo, geralmente mais do que a penalidade de executar um plano inferior ao ideal. Assim, o limite no tamanho da consulta é uma maneira conveniente de gerenciar o uso do GEQO.

geqo_effort (integer) #

Controla o balanço entre o tempo de planejamento e a qualidade do plano de consulta no GEQO. Esta variável deve ser um número inteiro no intervalo de 1 a 10. O padrão é 5. Valores maiores aumentam o tempo gasto no planejamento da consulta, mas também aumentam a probabilidade de escolha de um plano de consulta eficiente.

O parâmetro geqo_effort, na verdade, não faz nada diretamente; é usado apenas para calcular os valores padrão para os outros parâmetros que influenciam o comportamento do GEQO descrito abaixo). Se for preferido, pode-se definir os outros parâmetros manualmente.

geqo_pool_size (integer) #

Controla o tamanho do pool usado pelo GEQO, ou seja, o número de indivíduos na população genética. Deve ser pelo menos 2, e os valores úteis são normalmente de 100 a 1000. Se for definido como zero (a configuração padrão), o valor adequado é escolhido com base em geqo_effort e o número de tabelas na consulta.

geqo_generations (integer) #

Controla o número de gerações usadas pelo GEQO, ou seja, o número de iterações do algoritmo. Deve ser pelo menos 1, e os valores úteis estão no mesmo intervalo que o tamanho do conjunto. Se for definido como zero (a configuração padrão), o valor adequado é escolhido com base em geqo_pool_size.

geqo_selection_bias (floating point) #

Controla o viés de seleção usado pelo GEQO. O viés de seleção é a pressão seletiva dentro da população. Os valores podem ser de 1.50 a 2.00; este último é o padrão.

geqo_seed (floating point) #

Controla o valor inicial do gerador de números aleatórios usado pelo GEQO para selecionar caminhos aleatórios através do espaço de procura de ordem de junção. O valor pode variar de zero (o padrão) a 1. A variação do valor altera o conjunto de caminhos de junção explorados, podendo resultar na localização de um caminho melhor ou pior.

19.7.4. Outras opções do planejador #

default_statistics_target (integer) #

Define a meta de estatísticas padrão para as colunas de tabelas sem uma meta específica de coluna definida por meio do comando ALTER TABLE SET STATISTICS. Valores maiores aumentam o tempo necessário para o comando ANALYZE, mas podem melhorar a qualidade das estimativas do planejador. O padrão é 100. Para obter mais informações sobre o uso de estatísticas pelo planejador de consultas do PostgreSQL, veja Estatísticas usadas pelo planejador.

constraint_exclusion (enum) #

Controla o uso de restrições de tabela pelo planejador de consultas para otimizar as consultas. Os valores permitidos para constraint_exclusion são on (examina as restrições para todas as tabelas), off (nunca examina as restrições), e partition (examina as restrições apenas para tabelas filhas por herança e subconsultas UNION ALL). O padrão é partition. É frequentemente usado com árvores de herança tradicionais para melhorar o desempenho.

Quando este parâmetro o permite para uma tabela específica, o planejador compara as condições da consulta com as restrições CHECK da tabela, e omite a varredura de tabelas para as quais as condições contradizem as restrições. Por exemplo:

CREATE TABLE parent(key integer, ...);
CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent);
CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent);
...
SELECT * FROM parent WHERE key = 2400;

Com a exclusão de restrição ativa, este SELECT não fará a varredura de child1000, melhorando o desempenho.

No momento, a exclusão de restrição está ativa por padrão apenas para os casos onde são frequentemente usadas para implementar o particionamento de tabelas por meio de árvores de herança. Ativar, para todas as tabelas, impõe uma sobrecarga extra de planejamento que é bastante perceptível em consultas simples e, geralmente, não traz nenhum benefício para consultas simples. Se não existirem tabelas particionadas usando a herança tradicional, talvez se prefira desativar inteiramente. (Note-se que o recurso equivalente para tabelas particionadas é controlado por um parâmetro separado, o enable_partition_pruning.)

Veja Particionamento e exclusão de restrição para obter mais informações sobre como usar a exclusão de restrição para implementar o particionamento.

cursor_tuple_fraction (floating point) #

Define a estimativa feita pelo planejador, da fração das linhas que serão recuperadas por um cursor. O padrão é 0.1. Valores menores dessa configuração levam o planejador a usar planos de início rápido para os cursores, que vão recuperar as primeiras linhas rapidamente, embora levem muito tempo para buscar todas as linhas. Valores maiores colocam mais ênfase no tempo total estimado. Na configuração máxima de 1.0, os cursores são planejados como as consultas normais, considerando apenas o tempo total estimado, e não a rapidez com que as primeiras linhas podem ser entregues.

from_collapse_limit (integer) #

O planejador irá mesclar as subconsultas nas consultas superiores, se a lista FROM resultante não tiver mais do que esta quantidade de itens. Valores menores reduzem o tempo de planejamento, mas podem gerar planos de consulta inferiores. O padrão é 8. Veja Controle do planejador usando cláusulas JOIN explícitas para obter mais informações.

Definir este valor como geqo_threshold, ou maior, pode acionar o uso do planejador GEQO, resultando em planos não ideais. Veja Otimizador de consultas genético.

jit (boolean) #

Determina se a compilação JIT pode ser usada pelo PostgreSQL, se disponível (veja Compilação Just-in-Time (JIT)). O padrão é on.

join_collapse_limit (integer) #

O planejador irá reescrever as construções JOIN explícitas (exceto FULL JOIN) em listas de itens FROM, sempre que resultar em uma lista de não mais do que esta quantidade de itens. Valores menores reduzem o tempo de planejamento, mas podem gerar planos de consulta inferiores.

Por padrão, esta variável é configurada o mesmo que from_collapse_limit, apropriado para a maioria dos usos. Definir como 1 evita qualquer reordenação de JOINs explícitos. Assim, a ordem de junção explícita especificada na consulta será a ordem real pela qual as relações serão juntadas. Como o planejador de consultas nem sempre escolhe a ordem de junção ideal, os usuários avançados podem optar por definir temporariamente esta variável como 1 e, em seguida, especificar explicitamente a ordem de junção que desejam. Veja Controle do planejador usando cláusulas JOIN explícitas para obter mais informações.

Definir este valor como geqo_threshold, ou maior, pode acionar o uso do planejador GEQO, resultando em planos não ideais. Veja Otimizador de consultas genético para obter mais informações.

plan_cache_mode (enum) #

As instruções preparadas (preparadas explicitamente, ou geradas implicitamente, por exemplo, pelo PL/pgSQL), podem ser executadas usando planos personalizados ou genéricos. Os planos personalizados são refeitos para cada execução usando seu conjunto específico de valores de parâmetros, enquanto os planos genéricos não dependem dos valores de parâmetros, podendo ser reutilizados nas execuções. Assim, o uso de um plano genérico economiza tempo de planejamento, mas se o plano ideal depender fortemente dos valores dos parâmetros, um plano genérico poderá ser ineficiente. A escolha entre estas opções é normalmente feita automaticamente, mas pode ser estabelecida por plan_cache_mode. Os valores permitidos são auto (o padrão), force_custom_plan e force_generic_plan. Esta configuração é considerada quando deve ser executado um plano em cache, e não quando é preparado. Veja PREPARE para obter mais informações.

recursive_worktable_factor (floating point) #

Define a estimativa do planejador para o tamanho médio da tabela de trabalho de uma consulta recursiva, como um múltiplo do tamanho estimado do termo inicial não recursivo da consulta. Isto ajuda o planejador a escolher o método mais adequado para juntar a tabela de trabalho às outras tabelas da consulta. O padrão é 10.0. Um valor menor, como 1.0, pode ser útil quando a recursão apresenta um baixo fan-out (fator de ramificação) de uma etapa para a seguinte, como, por exemplo, em consultas de caminho mais curto. Consultas de análise de grafos podem se beneficiar de valores maiores do que o padrão.