Os hints permitem substituir as decisões do otimizador de consultas do Hologres — como ordem de junção, método de junção, distribuição de dados e parâmetros GUC — sem alterar a lógica da consulta. Use hints quando o otimizador gerar um plano de execução subotimizado devido a estatísticas desatualizadas ou distribuição incomum de dados.
O Hologres V2.2 e versões posteriores suportam hints. Se sua instância executar a V2.1 ou anterior, atualize-a antes de usar hints.
Pré-requisitos
Antes de começar, verifique se você possui:
Uma instância do Hologres executando a V2.2 ou posterior
O parâmetro GUC
pg_hint_plan_enable_hintdefinido comoon
Ative os hints no nível da sessão:
SET pg_hint_plan_enable_hint=on;
Ou ative os hints no nível do banco de dados (entra em vigor para novas conexões):
ALTER DATABASE <dbname> SET pg_hint_plan_enable_hint=on;
Sintaxe de hint
Insira um hint imediatamente após a palavra-chave DML (SELECT, INSERT, UPDATE ou DELETE):
SELECT|UPDATE|INSERT|DELETE /*+HINT <HintName(params)> */ ...
Regras principais:
Delimite os hints entre
/*+HINTe*/.As palavras-chave de hint não diferenciam maiúsculas de minúsculas.
Um único bloco de hint pode conter várias palavras-chave.
Não inclua comentários dentro de um bloco de hint.
Se uma instrução SELECT tiver múltiplos blocos de hint consecutivos, apenas o primeiro terá efeito.
Palavras-chave de hint
A tabela a seguir lista todas as palavras-chave de hint suportadas.
|
Tipo |
Palavra-chave |
Descrição |
Versão |
|
Método de junção |
|
Força uma junção hash. |
V2.2+ |
|
|
Força uma junção por loop aninhado. |
V2.2+ |
|
|
Ordem de junção |
|
Força uma ordem de junção (árvore profunda à esquerda por padrão). |
V2.2+ |
|
|
Força uma ordem e direção de junção. Use parênteses |
V2.2+ |
|
|
Filtro de runtime |
|
Força um filtro de runtime para junções hash nas tabelas especificadas. |
V2.2+ |
|
GUC |
|
Define o valor de um parâmetro GUC durante a execução da consulta atual. Consulte Parâmetros GUC. |
V2.2+ |
|
Motion |
|
Força o broadcast da tabela especificada em uma operação JOIN. Na maioria dos casos, use em conjunto com |
V3.0+ |
|
|
Impede o broadcast da tabela especificada. |
V3.0+ |
|
|
|
Força a coleta (gather) da tabela especificada em uma operação JOIN. |
V2.2+ |
|
|
|
Impede a coleta da tabela especificada. |
V2.2+ |
Exemplos:
-- HashJoin
SELECT
/*+HINT HashJoin(table1 table2 table3) */
table1.a
FROM
table1
JOIN table2 ON table1.a = table2.a
JOIN table3 ON table1.a = table3.a;
-- NestLoop
SELECT /*+HINT NestLoop(table1 table2) */ * FROM table1 JOIN table2 ON table1.a = table2.a;
-- Leading (profunda à esquerda: junta table2 e table1 primeiro, depois table3)
SELECT /*+HINT Leading(table2 table1) */ table1.a FROM table1 JOIN table2 ON table1.a = table2.a;
-- Leading com pares de junção (parênteses controlam o formato da árvore)
-- Isso junta (table2 JOIN table1) e (table3 JOIN table4) independentemente, e então une os dois resultados.
SELECT
/*+HINT Leading((table2 table1) (table3 table4)) */
*
FROM
table1
LEFT JOIN table2 ON table1.a = table2.a
RIGHT JOIN table3 ON table1.a = table3.a
LEFT JOIN table4 ON table3.a = table4.a
ORDER BY
table1.a;
-- RuntimeFilter
SELECT /*+HINT RuntimeFilter(table1 table2) */ * FROM table1 JOIN table2 ON table1.a = table2.a;
-- GUC: desativa a reutilização de count distinct apenas para esta consulta
EXPLAIN
SELECT
/*+HINT set(hg_experimental_enable_reuse_cte_of_count_distinct off) */
count(DISTINCT a),
count(DISTINCT b)
FROM table1;
Notas de uso
Objetos suportados
Os hints aplicam-se a tabelas regulares (incluindo tabelas externas), subconsultas e expressões de tabela comuns (CTEs). Views não são suportadas.
Escopo do hint
Um hint aplica-se somente ao nível de consulta onde está inserido. Um hint na consulta pai não pode referenciar tabelas em uma subconsulta, e vice-versa. No exemplo a seguir, Leading(tt t2) só pode referenciar tt e t2; já Leading(t t1) só pode referenciar t e t1.
SELECT /*+HINT Leading(t t1) */ * FROM t1 JOIN (
SELECT /*+HINT Leading(tt t2) */ * FROM t2 JOIN (
SELECT * FROM t3
) tt
) t;
Exceção — Hints GUC: Um hint GUC entra em vigor para toda a consulta, mesmo se colocado em uma subconsulta. Consultas subsequentes não são afetadas.
-- O hint GUC na subconsulta aplica-se a toda a consulta externa.
SELECT
count(DISTINCT a),
count(DISTINCT b)
FROM (
SELECT
/*+HINT set(hg_experimental_enable_reuse_cte_of_count_distinct off) */
t1.a, t2.b
FROM
t1
JOIN t2 ON t1.a = t2.a)
Hint Leading: controle do formato da árvore de junção
Sem parênteses, o Leading constrói uma árvore profunda à esquerda: Leading(t1 t2 t3) junta t1 e t2 primeiro, e depois o resultado com t3.
Use parênteses para controlar explicitamente o formato da árvore:
|
Sintaxe |
Formato da árvore |
Ordem de junção |
|
|
Profunda à esquerda |
(t1 ⋈ t2) ⋈ t3 |
|
|
Profunda à direita |
t1 ⋈ (t2 ⋈ t3) |
Parênteses aninhados são suportados.
Resolução de conflitos
Quando hints do mesmo tipo entram em conflito, apenas o primeiro tem efeito. Conflitos ocorrem quando:
Dois hints especificam as mesmas tabelas.
Dois hints especificam conjuntos idênticos de tabelas.
As tabelas em um hint de ordem de junção são um subconjunto das tabelas em outro.
Os conjuntos de tabelas em dois hints de método de junção, filtro de runtime ou junção skew não são subconjuntos um do outro.
Exemplos:
-- HashJoin(t1 t2) e NestLoop(t2 t1) conflitam (mesmas tabelas). Apenas HashJoin(t1 t2) é aplicado.
SELECT /*+HINT HashJoin(t1 t2) NestLoop(t2 t1) */ ...
-- Leading(t1 t2) é um subconjunto de Leading(t1 t2 t3). Apenas Leading(t1 t2) é aplicado.
SELECT /*+HINT Leading(t1 t2) Leading(t1 t2 t3) */ ...
Hints de método de junção e filtro de runtime
São necessários pelo menos dois parâmetros válidos. Parâmetros válidos incluem tabelas, subconsultas ou CTEs no nível de consulta onde o hint se aplica. Por exemplo,
Leading(t1 t1)possui apenas um parâmetro válido.Caso o plano candidato gerado não inclua a junção especificada por um hint de método de junção, o hint não terá efeito. Por exemplo,
HashJoin(t1 t2)não surte efeito se o plano juntar t1 com t3 primeiro e depois juntar t2. Nesse cenário, adicioneLeading(t1 t2)para forçar a ordem de junção.Hints de filtro de runtime funcionam exclusivamente em junções hash.
INSERT INTO ... SELECT
O hint INSERT aplica-se à tabela de destino e à tabela de origem do SELECT mais externo. Não especifique hints nas cláusulas INSERT e SELECT simultaneamente:
-- Correto: hint no INSERT
INSERT /*+HINT Leading(target (t1 t2)) */ INTO target SELECT t1.a, t2.b FROM t1 JOIN t2 ON t1.a=t2.a;
-- Correto: hint no SELECT
INSERT INTO target SELECT /*+HINT Leading(t2 t1) */ t1.a, t2.b FROM t1 JOIN t2 ON t1.a=t2.a;
-- Incorreto: hints tanto no INSERT quanto no SELECT — resulta em erro
INSERT /*+HINT Leading(target (t1 t2)) */ INTO target SELECT /*+HINT Leading(t2 t1) */ t1.a, t2.b FROM t1 JOIN t2 ON t1.a=t2.a;
-- ERROR: insert statement with hint should not have sub select with hint at the same time
Cenários
Os exemplos a seguir utilizam estas tabelas:
CREATE TABLE target (a int primary key, b int);
CREATE TABLE t1 (a int, b int);
CREATE TABLE t2 (a int, b int);
CREATE TABLE t3 (a int);
CREATE TABLE t4 (a int);
Ajuste da ordem de junção
Estatísticas desatualizadas representam a causa mais comum para uma ordem de junção subotimizada. Isso ocorre quando a instrução ANALYZE não foi executada recentemente ou quando a contagem real de linhas após um filtro ou junção difere significativamente da estimativa. Consulte ANALYZE e AUTO ANALYZE.
Em uma junção hash, o Hologres usa a tabela menor para construir a tabela hash (exibida na parte inferior do operador Hash no plano de execução). Se t2 tiver mais linhas que t1, mas o otimizador escolher t1 como lado de construção, use um hint Leading para inverter a ordem de junção.
SELECT /*+HINT Leading(t2 t1) */ t1.a FROM t1 JOIN t2 ON t1.a = t2.a;
Plano de execução sem hint:
QUERY PLAN
-----------------------------------------------------------------------------------
Gather (cost=0.00..10.07 rows=1000 width=4)
-> Hash Join (cost=0.00..10.05 rows=1000 width=4)
Hash Cond: (t1.a = t2.a)
-> Redistribution (cost=0.00..5.01 rows=1000 width=4)
Hash Key: t1.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=4)
-> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=4)
-> Hash (cost=5.01..5.01 rows=1000 width=4)
-> Redistribution (cost=0.00..5.01 rows=1000 width=4)
Hash Key: t2.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=4)
-> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=4)
Plano de execução com hint:
QUERY PLAN
-----------------------------------------------------------------------------------
Gather (cost=0.00..10.07 rows=1000 width=4)
-> Hash Join (cost=0.00..10.05 rows=1000 width=4)
Hash Cond: (t2.a = t1.a)
-> Redistribution (cost=0.00..5.01 rows=1000 width=4)
Hash Key: t2.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=4)
-> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=4)
-> Hash (cost=5.01..5.01 rows=1000 width=4)
-> Redistribution (cost=0.00..5.01 rows=1000 width=4)
Hash Key: t1.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=4)
-> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=4)
Agora t2 constrói a tabela hash, que é o comportamento esperado quando t2 é menor.
Aplicação de um hint GUC
Hints GUC configuram um parâmetro GUC para uma única consulta. O parâmetro reverte após a conclusão da consulta e não afeta outras consultas.
SELECT /*+HINT set(hg_experimental_query_batch_size 512) */ t1.a FROM t1 JOIN t2 ON t1.a = t2.a;
Plano de execução:
QUERY PLAN
Hash Join (cost=0.00..10.00 rows=1 width=4)
Hash Cond: (t1.a = t2.a)
-> Gather (cost=0.00..5.00 rows=1 width=4)
-> Local Gather (cost=0.00..5.00 rows=1 width=4)
-> Seq Scan on t1 (cost=0.00..5.00 rows=1 width=4)
-> Hash (cost=5.00..5.00 rows=1 width=4)
-> Gather (cost=0.00..5.00 rows=1 width=4)
-> Local Gather (cost=0.00..5.00 rows=1 width=4)
-> Seq Scan on t2 (cost=0.00..5.00 rows=1 width=4)
Uso de hints em CTEs e subconsultas
Hints em CTEs e subconsultas controlam individualmente a estratégia de junção em seus próprios níveis de consulta. O exemplo a seguir aplica múltiplos hints em diferentes níveis de consulta.
WITH c1 AS (
SELECT /*+HINT Leading(t2 t1) */ t1.a FROM (
(
SELECT /*+HINT leading(t2 t1) */ t1.a FROM t1 JOIN t2 ON t1.a = t2.a
) AS t1
JOIN
(
SELECT /*+HINT NestLoop(t4 t3) */ t4.a FROM t3 JOIN t4 ON t3.a = t4.a
) AS t2
ON t1.a = t2.a
)
),
c2 AS (
SELECT /*+HINT leading(t1 t2) */ t2.a FROM (
(
SELECT /*+HINT Leading(t1 t2) */ t1.a FROM t1 JOIN t2 ON t1.a = t2.a
) AS t1
JOIN
(
SELECT /*+HINT Leading(t4 t3) */ t4.a FROM t3 JOIN t4 ON t3.a = t4.a
) AS t2
ON t1.a = t2.a
)
)
SELECT /*+HINT NestLoop(v2 v1) */ * FROM (
(
SELECT /*+HINT Leading (c1 t2) */ c1.a FROM c1 JOIN t2 ON c1.a = t2.a
) AS v1
JOIN
(
SELECT /*+HINT Leading (t1 c2) */ c2.a FROM t1 JOIN c2 ON t1.a = c2.a
) AS v2
ON v1.a = v2.a
)
ORDER BY v2.a;
Uso de hints em instruções INSERT
Use hints INSERT quando a tabela de destino participar de uma junção com tabelas de origem e a ordem de junção padrão for subotimizada.
Exemplo 1: Hint na cláusula INSERT
O hint aplica-se à tabela de destino e à tabela de origem do SELECT mais externo. Use esta abordagem quando o resultado de t1 JOIN t2 for pequeno, mas a tabela de destino target for grande.
INSERT /*+HINT Leading(target (t1 t2)) */ INTO target SELECT t1.a, t2.b FROM t1 JOIN t2 ON t1.a=t2.a;
Plano de execução:
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------
Gather (cost=0.00..26.57 rows=1000 width=8)
-> Insert (cost=0.00..26.54 rows=1000 width=8)
-> Project (cost=0.00..16.12 rows=1000 width=8)
-> Hash Right Join (cost=0.00..15.12 rows=1000 width=12)
Hash Cond: (target.a = t1.a)
-> Local Gather (cost=0.00..5.00 rows=1000 width=4)
-> Seq Scan on target (cost=0.00..5.00 rows=1000 width=4)
-> Hash (cost=10.07..10.07 rows=1000 width=8)
-> Redistribution (cost=0.00..10.07 rows=1000 width=8)
Hash Key: t1.a
-> Hash Join (cost=0.00..10.06 rows=1000 width=8)
Hash Cond: (t1.a = t2.a)
-> Redistribution (cost=0.00..5.01 rows=1000 width=4)
Hash Key: t1.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=4)
-> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=4)
-> Hash (cost=5.01..5.01 rows=1000 width=8)
-> Redistribution (cost=0.00..5.01 rows=1000 width=8)
Hash Key: t2.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=8)
-> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=8)
Exemplo 2: Hint na cláusula SELECT
As duas instruções a seguir produzem o mesmo efeito:
INSERT INTO target SELECT /*+HINT Leading(t2 t1) */ t1.a, t2.b FROM t1 JOIN t2 ON t1.a=t2.a;
INSERT /*+HINT Leading(t2 t1) */ INTO target SELECT t1.a, t2.b FROM t1 JOIN t2 ON t1.a=t2.a;
Uso de hints em instruções UPDATE
Use hints UPDATE quando a tabela de destino se juntar a uma tabela de origem e você precisar controlar a ordem de junção.
No exemplo a seguir, t1 possui mais linhas que target. O hint torna target o lado de construção da junção hash.
UPDATE /*+HINT Leading(t1 target) */ target SET b=t1.b+1 FROM t1 WHERE t1.a=target.a;
Plano de execução sem hint:
QUERY PLAN
-----------------------------------------------------------------------------------------------
Gather (cost=0.00..52.77 rows=1000 width=1)
-> Update (cost=0.00..52.76 rows=1000 width=1)
-> Project (cost=0.00..11.09 rows=1000 width=32)
-> Hash Join (cost=0.00..10.08 rows=1000 width=32)
Hash Cond: (target.a = t1.a)
-> Local Gather (cost=0.00..5.00 rows=1000 width=28)
-> Seq Scan on target (cost=0.00..5.00 rows=1000 width=28)
-> Hash (cost=5.01..5.01 rows=1000 width=8)
-> Redistribution (cost=0.00..5.01 rows=1000 width=8)
Hash Key: t1.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=8)
-> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=8)
Plano de execução com hint:
QUERY PLAN
----------------------------------------------------------------------------------------------
Gather (cost=0.00..52.77 rows=1000 width=1)
-> Update (cost=0.00..52.76 rows=1000 width=1)
-> Project (cost=0.00..11.09 rows=1000 width=32)
-> Hash Join (cost=0.00..10.08 rows=1000 width=32)
Hash Cond: (t1.a = target.a)
-> Redistribution (cost=0.00..5.01 rows=1000 width=8)
Hash Key: t1.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=8)
-> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=8)
-> Hash (cost=5.00..5.00 rows=1000 width=28)
-> Local Gather (cost=0.00..5.00 rows=1000 width=28)
-> Seq Scan on target (cost=0.00..5.00 rows=1000 width=28)
Agora target constrói a tabela hash, reduzindo o custo da junção.
Uso de hints de filtro de runtime
O Hologres suporta filtros de runtime para junções hash. Se uma consulta não atender às condições para acionar automaticamente um filtro de runtime, use um hint RuntimeFilter para forçá-lo.
Forçar um filtro de runtime nem sempre melhora o desempenho. Verifique o plano de execução antes de aplicar este hint em produção.
SELECT /*+HINT runtimefilter(t1 t2) */ * FROM t1 JOIN t2 ON t1.a = t2.a;
Plano de execução (a linha Runtime Filter Cond confirma que o filtro está ativo):
QUERY PLAN
-----------------------------------------------------------------------------------
Gather (cost=0.00..10.13 rows=1000 width=16)
-> Hash Join (cost=0.00..10.07 rows=1000 width=16)
Hash Cond: (t1.a = t2.a)
Runtime Filter Cond: (t1.a = t2.a)
-> Redistribution (cost=0.00..5.01 rows=1000 width=8)
Hash Key: t1.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=8)
-> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=8)
Runtime Filter Target Expr: t1.a
-> Hash (cost=5.01..5.01 rows=1000 width=8)
-> Redistribution (cost=0.00..5.01 rows=1000 width=8)
Hash Key: t2.a
-> Local Gather (cost=0.00..5.00 rows=1000 width=8)
-> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=8)
Uso de hints de motion
Hints de motion controlam como o Hologres distribui dados entre workers durante um JOIN — seja fazendo broadcast de uma tabela para todos os workers ou redistribuindo-a (shuffling).
Exemplo 1: Forçar broadcast
Use Broadcast quando as estatísticas estiverem imprecisas e o otimizador incorretamente fizer shuffle de uma grande quantidade de dados. Como uma junção hash só pode fazer broadcast no lado de construção, combine Broadcast com Leading para especificar a ordem correta de junção.
SELECT /*+HINT Leading(t2 t1) Broadcast(t1) */ * FROM t1 JOIN t2 ON t1.a = t2.a;
Plano de execução:
QUERY PLAN
----------------------------------------------------------------------------------------------
Gather (cost=0.00..100000000000000005366162204393472.00 rows=1000 width=16)
-> Hash Join (cost=0.00..100000000000000005366162204393472.00 rows=1000 width=16)
Hash Cond: (t2.a = t1.a)
-> Local Gather (cost=0.00..5.00 rows=1000 width=8)
-> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=8)
-> Hash (cost=100000000000000005366162204393472.00..100000000000000005366162204393472.00 rows=3000 width=8)
-> Broadcast (cost=0.00..100000000000000005366162204393472.00 rows=3000 width=8)
-> Local Gather (cost=0.00..5.00 rows=1000 width=8)
-> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=8)
Exemplo 2: Desativar broadcast
Use NoBroadcast quando o otimizador subestimar a contagem real de linhas de uma tabela e tentar fazer broadcast de uma tabela grande, resultando em desempenho muito ruim. Este hint requer Hologres V3.0 ou posterior.
Primeiro, crie as tabelas de teste:
-
Dados de amostra
CREATE TABLE test1(a int, b int); CREATE TABLE test2(a int, b int); INSERT INTO test1 SELECT 1, i FROM generate_series(1, 10) AS i; INSERT INTO test2 SELECT 1, i FROM generate_series(1, 1000000) AS i; ANALYZE test1, test2; -
Instruções SQL de amostra
Sem o hint, o otimizador faz broadcast de
test1(estimada em 200 linhas após estatísticas, mas com apenas 10 na realidade):Realizar broadcast sem usar um hint
EXPLAIN SELECT * FROM test1 JOIN test2 ON test1.b = test2.b;Usar um hint para desativar o broadcast
EXPLAIN SELECT /*+HINT NoBroadcast(test1) */ * FROM test1 JOIN test2 ON test1.b = test2.b; -
Plano de execução:
Com
NoBroadcast, o Hologres redistribui ambas as tabelas:Realizar broadcast sem usar um hint
QUERY PLAN --------------------------------------------------------------------------------- Gather (cost=0.00..51.98 rows=1000000 width=16) -> Hash Join (cost=0.00..13.12 rows=1000000 width=16) Hash Cond: (test2.b = test1.b) -> Local Gather (cost=0.00..5.23 rows=1000000 width=8) -> Seq Scan on test2 (cost=0.00..5.20 rows=1000000 width=8) -> Hash (cost=5.00..5.00 rows=200 width=8) -> Broadcast (cost=0.00..5.00 rows=200 width=8) -> Local Gather (cost=0.00..5.00 rows=10 width=8) -> Seq Scan on test1 (cost=0.00..5.00 rows=10 width=8)Usar um hint para desativar o broadcast
QUERY PLAN --------------------------------------------------------------------------------- Gather (cost=0.00..53.23 rows=1000000 width=16) -> Hash Join (cost=0.00..14.37 rows=1000000 width=16) Hash Cond: (test2.b = test1.b) -> Redistribution (cost=0.00..6.48 rows=1000000 width=8) Hash Key: test2.b -> Local Gather (cost=0.00..5.23 rows=1000000 width=8) -> Seq Scan on test2 (cost=0.00..5.20 rows=1000000 width=8) -> Hash (cost=5.00..5.00 rows=10 width=8) -> Redistribution (cost=0.00..5.00 rows=10 width=8) Hash Key: test1.b -> Local Gather (cost=0.00..5.00 rows=10 width=8) -> Seq Scan on test1 (cost=0.00..5.00 rows=10 width=8)
Verifique se os hints têm efeito
Execute EXPLAIN antes e depois de adicionar um hint. Confirme se a alteração no plano de execução corresponde à sua intenção — por exemplo, a ordem de Hash Cond muda ao trocar a ordem de junção com Leading, ou Runtime Filter Cond aparece ao aplicar RuntimeFilter.
Se o plano não mudar, verifique os seguintes pontos:
Hint não aplicado devido a conflito: Quando hints do mesmo tipo entram em conflito, apenas o primeiro é analisado. Remova hints duplicados ou conflitantes.
Parâmetros de hint inválidos: Hints de método de junção e ordem de junção exigem pelo menos dois parâmetros válidos (tabelas, subconsultas ou CTEs no mesmo nível de consulta).
Leading(t1 t1)tem apenas um parâmetro válido e não terá efeito.Plano incompatível com o hint: Se a combinação especificada for impossível (por exemplo,
NestLoopcom umRIGHT JOINem certas configurações de tabela), o Hologres retorna:ERROR: ORCA failed to produce a plan : No plan has been computed for required properties. Revise a combinação de hints e ajuste conforme necessário.