Modifica a GEQO (ottimizzazione di query genetiche) di PostgreSQL


16

Devo implementare una funzionalità in linea con la funzionalità GEQO di PostgreSQL. Comprendo che l'approccio GEQO consiste nel codificare i piani di query come stringhe di numeri interi e GEQO genera queste possibili sequenze di join a caso. Fonte: http://www.postgresql.org/docs/9.3/static/geqo-pg-intro.html

La mia domanda: come modificare la funzione GEQO se conosco definitivamente la giusta sequenza di join, in modo da non dover cercare diverse sequenze di join. Ad esempio, se sapessi che il modo migliore di unire le 4 relazioni è 4-1-3-2, non devo controllare altre permutazioni.

Non ci sono buoni materiali su come GEQO è implementato in PostgreSQL. PostgreSQL offre solo una visione d'insieme della funzionalità GEQO ma non spiega molto.

O potrei ottenere questa funzionalità in standard_join_search () stesso senza usare GEQO?


3
Sembra che tu voglia implementare suggerimenti per le query. Va tutto bene, ma non dovresti aspettarti di ottenere il cambiamento accettato nel core di PostgreSQL perché la community del progetto non è quella che chiameresti un grande fan dei suggerimenti per le query. Se sei serio su questo, dovrai leggere un po 'del codice del planner di query e dovrai capire come passare i tuoi suggerimenti dal parser attraverso il rewriter e nel planner. Non vedo una risposta semplice e veloce qui. Quello che vuoi fare alla fine è forzare una scelta di percorso particolare nel planner / ottimizzatore.
Craig Ringer

Ah, sì, sono scettici sui suggerimenti per le query. Ho letto il codice del planner e sembrava che GEQO sarebbe stato un modo per ridurre al minimo le modifiche al core esistente.
user2761431

2
È questo ciò che stai cercando di ottenere, implementare suggerimenti di query per forzare l'ordinamento dei join? In tal caso, verifica se qualcun altro lo ha già implementato. Dovresti anche considerare perché ne hai bisogno, perché il pianificatore sta facendo le scelte sbagliate in primo luogo. Prendi in considerazione la possibilità di produrre un caso di test autonomo e di riferire a pgsql-performance.
Craig Ringer,

3
C'è pg_hint_plan : en.sourceforge.jp/projects/pghintplan , ma non l'ho usato. Un dba mi ha detto che funzionava al 9.2. C'è anche un articolo in russo a riguardo habrahabr.ru/post/169751
ckorzhik,

Risposte:


1

Un modo per farlo senza la necessità di giocare con GEKO è usare CTE.

I CTE sono barriere di ottimizzazione, quindi è possibile avvolgere i join all'interno dei CTE nell'ordine desiderato e PG sarà costretto a farlo.

Ad esempio, se vogliamo forzare il DB a unire prima t1 con t2 e solo allora con t4 potremmo eseguire qualcosa del tipo:

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;

Ciò comporterà:

                                  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)

Questo è solo un esempio, puoi cambiarlo secondo necessità - in ogni caso PG non può cambiare l'ordine tra i diversi CTE.

Spero che sia d'aiuto :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.