Modificação no GEQO (Otimização de Consulta Genética) do PostgreSQL

16

Preciso implementar uma funcionalidade que esteja alinhada com a funcionalidade GEQO do PostgreSQL. Entendo que a abordagem do GEQO é codificar planos de consulta como seqüências de caracteres inteiras e o GEQO gera essas possíveis sequências de junção aleatoriamente. Fonte: http://www.postgresql.org/docs/9.3/static/geqo-pg-intro.html

Minha pergunta: como modificar a função GEQO se eu souber definitivamente a sequência de junção correta, para que eu não precise pesquisar diferentes sequências de junção. Por exemplo, se eu sabia que a melhor maneira de ingressar nas 4 relações é 4-1-3-2, não preciso verificar outras permutações.

Não existem bons materiais sobre como o GEQO é implementado no PostgreSQL. O PostgreSQL fornece apenas uma visão geral da funcionalidade do GEQO, mas não explica muito.

Ou eu poderia conseguir essa funcionalidade no próprio standard_join_search () sem usar o GEQO?

user2761431
fonte
3
Parece que você deseja implementar dicas de consulta. Tudo bem, mas você não deve esperar que a alteração seja aceita no núcleo do PostgreSQL, porque a comunidade do projeto não é o que você chamaria de grande fã de dicas de consulta. Se você é sério sobre isso, precisará ler bastante o código do planejador de consultas e descobrir como passar suas dicas do analisador para o reescritor e para o planejador. Não vejo uma resposta rápida e simples aqui. O que você deseja fazer é forçar uma escolha de caminho específica no planejador / otimizador.
Craig Ringer
Ah, sim, eles são céticos quanto às dicas de consulta. Fiz a leitura do código do planejador e parecia que o GEQO seria uma maneira de minimizar as alterações no núcleo existente.
User2761431
2
É isso que você está tentando alcançar, para implementar dicas de consulta para forçar a ordem de junção? Nesse caso, verifique se alguém já o implementou. Você também deve considerar por que precisa, por que o planejador está fazendo as escolhas erradas em primeiro lugar. Considere produzir um caso de teste independente e reportar ao pgsql-performance.
Craig Ringer
3
Existe pg_hint_plan : en.sourceforge.jp/projects/pghintplan , mas não o usei. Um dba me disse que estava trabalhando no 9.2. Há também um artigo em russo sobre isso habrahabr.ru/post/169751 #
58675 ckorzhik

Respostas:

1

Uma maneira de fazer isso sem a necessidade de mexer com o GEKO é usando o CTE.

CTE são barreiras de otimização, portanto, você pode agrupar as junções dentro de CTEs na ordem que desejar e o PG será forçado a fazê-lo.

Por exemplo, se queremos forçar o banco de dados a ingressar primeiro em t1 com t2 e somente depois em t4, podemos executar algo como:

explain 
with j1 as (select *,t1.c4 as t1c4 from t1 join t2 on (t1.c2=t2.id))
    ,j2 as (select * from j1 join t4 on (t1c4=t4.id))
select * from j2;

Isso resultará em:

                                  QUERY PLAN                                   
-------------------------------------------------------------------------------
CTE Scan on j2  (cost=51485.00..67785.00 rows=815000 width=64)
CTE j1
 ->  Hash Join  (cost=3473.00..14521.00 rows=815000 width=40)
       Hash Cond: (t2.id = t1.c2)
       ->  Seq Scan on t2  (cost=0.00..26.30 rows=1630 width=20)
       ->  Hash  (cost=1637.00..1637.00 rows=100000 width=20)
             ->  Seq Scan on t1  (cost=0.00..1637.00 rows=100000 width=20)
CTE j2
 ->  Hash Join  (cost=289.00..36964.00 rows=815000 width=64)
       Hash Cond: (j1.t1c4 = t4.id)
       ->  CTE Scan on j1  (cost=0.00..16300.00 rows=815000 width=44)
       ->  Hash  (cost=164.00..164.00 rows=10000 width=20)
             ->  Seq Scan on t4  (cost=0.00..164.00 rows=10000 width=20)
(13 rows)

Este é apenas um exemplo, você pode alterá-lo conforme necessário - em qualquer caso, o PG não pode alterar a ordem entre os diferentes CTEs.

Espero que ajude :)

cohenjo
fonte