A extensão pg_hint_plan permite substituir o planejador baseado em custo do PostgreSQL por hints incorporados em comentários SQL, como /*+ SeqScan(orders) */. Utilize-a quando o planejador selecionar um plano de consulta subotimizado impossível de corrigir apenas com atualizações de estatísticas ou alterações de índices.
Pré-requisitos
Antes de começar, verifique se você possui:
Uma instância RDS PostgreSQL 10 ou superior
Uma conta privilegiada na instância. Para criar uma, consulte Criar uma conta
Para o RDS PostgreSQL 17, a versão secundária do mecanismo deve ser 20241030 ou posterior. Caso não consiga criar a extensão, atualize a versão secundária do mecanismo primeiro.
Como funciona
O PostgreSQL utiliza um otimizador baseado em custo que estima o custo de cada plano de consulta possível e seleciona aquele com o menor valor. Como o otimizador trabalha com base em estatísticas, e não no seu conhecimento sobre os dados, ele pode ignorar padrões inerentes aos dados e escolher um plano subotimizado.
O pg_hint_plan lê hints especiais de comentários SQL e os transmite ao planejador antes da otimização. Isso permite especificar o método de varredura, o método de junção, a ordem de junção e outros comportamentos do planejador para uma consulta específica, sem modificar os dados ou as estatísticas.
Instale a extensão
Instalação pelo console
Acesse a lista de instâncias RDS, selecione uma região e clique em ID da instância.
No painel de navegação à esquerda, clique em Plug-ins.
-
Na página Extension Management, clique em aba Uninstalled Extensions, pesquise por pg_hint_plan e clique em Install na coluna Actions.

Na caixa de diálogo, selecione o banco de dados de destino e uma conta privilegiada, depois clique em OK.
A instalação da extensão é concluída quando o status da instância muda de Maintaining Instance para Running.
Instalação via SQL
-
Defina os parâmetros da instância para adicionar
pg_hint_planao Running Value deshared_preload_libraries. Por exemplo:'pg_stat_statements,auto_explain,pg_hint_plan' -
Com uma conta privilegiada, conecte-se ao banco de dados onde deseja instalar a extensão e execute:
CREATE EXTENSION pg_hint_plan;
Atualize ou desinstale a extensão
Na página Extension Management, clique em aba Installed Extensions:
Para atualizar: clique em Upgrade na coluna Actions. Se o botão Upgrade não aparecer, a extensão já está na versão mais recente.
Para desinstalar: clique em Uninstall na coluna Actions.
Para desinstalar via SQL:
DROP EXTENSION pg_hint_plan;
Escrever hints em comentários
Insira os hints em um comentário de bloco que começa com /*+ e termina com */, imediatamente antes da instrução SQL. Cada hint consiste em um nome e seus parâmetros entre parênteses, separados por espaços.
Usar aliases de tabela nos hints
Se uma consulta utilizar um alias de tabela, o hint deve referenciar o alias, e não o nome original da tabela. O uso do nome original faz com que o sistema ignore o hint silenciosamente.
Hint com alias (efetivo):
Usar a tabela de hints para SQL não editável
Quando não for possível modificar diretamente a instrução SQL, armazene os hints na tabela hint_plan.hints. Os hints nesta tabela têm precedência sobre os hints em comentários inline.
Por padrão, o usuário que cria a extensão pg_hint_plan possui permissões na tabela hint_plan.hints.
A tabela possui as seguintes colunas:
|
Coluna |
Descrição |
|
|
Identificador único da linha, gerado automaticamente. |
|
|
Padrão correspondente à instrução SQL alvo. Substitua todas as constantes por |
|
|
Nome da aplicação para escopo do hint. Deixe em branco para aplicar a todas as aplicações. |
|
|
Conteúdo do hint, sem as marcas de comentário |
Ative a tabela de hints
SET pg_hint_plan.enable_hint_table = on;
Gerencie hints na tabela
Inserir um hint:
INSERT INTO hint_plan.hints (norm_query_string, application_name, hints)
VALUES (
'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;',
'',
'SeqScan(t1)'
);
Atualize um hint:
UPDATE hint_plan.hints
SET hints = 'IndexScan(t1)'
WHERE id = 1;
Exclua um hint:
DELETE FROM hint_plan.hints
WHERE id = 1;
Tipos de hints
O pg_hint_plan suporta seis categorias de hints.
Hints de método de varredura
Forçam ou proíbem um método específico de varredura em uma tabela. Se a tabela possuir um alias na consulta, utilize-o no hint.
Válido em: tabelas comuns, tabelas herdadas, tabelas unlogged, tabelas temporárias, tabelas de sistema.
Não válido em: tabelas externas, funções de tabela, expressões de valor constante, expressões universais, views, subconsultas.
Exemplo — forçar uma varredura sequencial em t1 e uma varredura de índice em t2:
Hints de método de junção
Forçam ou proíbem um método específico de junção entre tabelas.
Válido em: tabelas comuns, tabelas herdadas, tabelas unlogged, tabelas temporárias, tabelas externas, tabelas de sistema, funções de tabela, expressões de valor constante, expressões universais.
Não válido em: views, subconsultas.
Hints de ordem de junção
Controlam a ordem em que as tabelas são unidas. Duas formas estão disponíveis:
-
Especificar apenas a ordem de junção (direção escolhida pelo planejador):
/*+ Leading(t1 t2 t3) */ SELECT * FROM table1 t1 JOIN table2 t2 ON (t1.key = t2.key) JOIN table3 t3 ON (t2.key = t3.key); -
Especificar a ordem e a direção da junção em cada nível:
/*+ Leading((t1 t2) t3) */ SELECT * FROM table1 t1 JOIN table2 t2 ON (t1.key = t2.key) JOIN table3 t3 ON (t2.key = t3.key);
Hints de correção de número de linhas
Corrigem estimativas de contagem de linhas incorretas feitas pelo otimizador. Quatro métodos de correção estão disponíveis:
Hints de execução paralela
Definem o número de workers paralelos para uma tabela. Configure a contagem de workers como 0 para desativar a execução paralela.
O terceiro parâmetro controla quais configurações são alteradas:
soft(padrão): altera apenasmax_parallel_workers_per_gather; o planejador controla as demais configurações.hard: altera todas as configurações relacionadas do planejador.
Válido em: tabelas comuns, tabelas herdadas, tabelas unlogged, tabelas de sistema. Tabelas internas de uma view podem ser referenciadas pelo nome real ou alias.
Não válido em: tabelas externas, cláusulas de valor constante, expressões universais, views, subconsultas.
Exemplo — executar uma consulta de junção com 3 workers em c1 e 5 workers em c2:
Hints de parâmetros GUC
Alteram temporariamente o valor de um parâmetro GUC durante o planejamento da consulta. Se o mesmo parâmetro GUC for definido mais de uma vez, o último valor prevalecerá.
Formatos de hints suportados
| Categoria | Formato | Descrição |
|---|---|---|
| Métodos de varredura | SeqScan(table) |
Força uma varredura sequencial. |
TidScan(table) |
Força uma varredura TID (identificador de tupla). | |
IndexScan(table [index...]) |
Força uma varredura de índice. Opcionalmente, especifique o índice. | |
IndexOnlyScan(table [index...]) |
Força uma varredura somente de índice. Opcionalmente, especifique o índice. | |
BitmapScan(table [index...]) |
Força uma varredura de bitmap. | |
NoSeqScan(table) |
Proíbe uma varredura sequencial. | |
NoTidScan(table) |
Proíbe uma varredura TID. | |
NoIndexScan(table) |
Proíbe uma varredura de índice. | |
NoIndexOnlyScan(table) |
Proíbe uma varredura somente de índice. Apenas tabelas são varridas. | |
NoBitmapScan(table) |
Proíbe uma varredura de bitmap. | |
| Métodos de junção | NestLoop(table table [table...]) |
Força uma junção nested loop. |
HashJoin(table table [table...]) |
Força uma junção hash. | |
MergeJoin(table table [table...]) |
Força uma junção merge. | |
NoNestLoop(table table [table...]) |
Proíbe uma junção nested loop. | |
NoHashJoin(table table [table...]) |
Proíbe uma junção hash. | |
NoMergeJoin(table table [table...]) |
Proíbe uma junção merge. | |
| Ordem de junção | Leading(table table [table...]) |
Especifica a ordem de junção. |
Leading(<join pair>) |
Especifica a ordem e a direção da junção em cada nível. | |
| Correção de número de linhas | Rows(table table [table...] correction) |
Corrige a contagem estimada de linhas para uma junção. Métodos de correção: #<n> (definir como n), +<n> (adicionar n), -<n> (subtrair n), *<n> (multiplicar por n). <n> deve ser legível pela função strtod. |
| Execução paralela | Parallel(table <workers> [soft|hard]) |
Define ou proíbe a execução paralela. Defina <workers> como 0 para desativar. Padrão: soft. |
| Parâmetros GUC | Set(GUC-param value) |
Define o valor de um parâmetro GUC durante o planejamento da consulta. |
Para mais informações, consulte pg_hint_plan.