Modification de GEQO (Genetic Query Optimization) de PostgreSQL

16

J'ai besoin d'implémenter une fonctionnalité conforme à la fonctionnalité GEQO de PostgreSQL. Je comprends que l'approche GEQO consiste à coder les plans de requête sous forme de chaînes entières et GEQO génère ces séquences de jointure possibles au hasard. Source: http://www.postgresql.org/docs/9.3/static/geqo-pg-intro.html

Ma question: comment modifier la fonction GEQO si je connais définitivement la bonne séquence de jointure, pour ne pas avoir à rechercher différentes séquences de jointure. Par exemple, si je savais que la meilleure façon de rejoindre les 4 relations est le 4-1-3-2, je n'ai pas besoin de vérifier d'autres permutations.

Il n'y a pas de bons matériaux sur la façon dont GEQO est implémenté dans PostgreSQL. PostgreSQL ne donne qu'une vue d'ensemble de la fonctionnalité GEQO mais n'explique pas grand-chose.

Ou pourrais-je obtenir cette fonctionnalité dans le standard_join_search () lui-même sans utiliser GEQO?

user2761431
la source
3
Il semble que vous souhaitiez implémenter des conseils de requête. C'est bien beau, mais vous ne devriez pas vous attendre à ce que le changement soit accepté dans le cœur de PostgreSQL car la communauté du projet n'est pas ce que vous appelleriez un grand fan d'indices de requête. Si vous êtes sérieux à ce sujet, vous devrez lire un peu le code du planificateur de requêtes et vous devrez comprendre comment transmettre vos conseils de l'analyseur à travers le réécrivain et dans le planificateur. Je ne vois pas de réponse rapide et simple ici. Ce que vous voulez éventuellement faire, c'est forcer un choix de chemin particulier dans le planificateur / optimiseur.
Craig Ringer
Ah, oui, ils sont sceptiques quant aux indices de requête. J'ai fait la lecture du code du planificateur et il me semblait que GEQO serait un moyen de minimiser les modifications apportées au noyau existant.
user2761431
2
Est-ce ce que vous essayez de réaliser, d'implémenter des conseils de requête pour forcer l'ordre de jointure? Si oui, vérifiez si quelqu'un d'autre l'a déjà implémenté. Vous devriez également considérer pourquoi vous en avez besoin, pourquoi le planificateur fait les mauvais choix en premier lieu. Envisagez de produire un scénario de test autonome et de faire rapport à pgsql-performance.
Craig Ringer
3
Il y a pg_hint_plan : en.sourceforge.jp/projects/pghintplan , mais je ne l'ai pas utilisé. Un dba m'a dit qu'il travaillait sur 9.2. Il y a aussi un article en russe à ce sujet habrahabr.ru/post/169751
ckorzhik

Réponses:

1

Une façon de le faire sans avoir besoin de jouer avec GEKO est d'utiliser CTE.

Les CTE sont des barrières d'optimisation, vous pouvez donc envelopper les jointures à l'intérieur des CTE dans l'ordre que vous souhaitez et PG sera obligé de le faire.

Par exemple, si nous voulons forcer la base de données à rejoindre d'abord t1 avec t2 et ensuite seulement avec t4, nous pourrions exécuter quelque chose comme:

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;

Cela se traduira par:

                                  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)

Ceci est juste un exemple, vous pouvez le changer selon vos besoins - en tout cas, PG ne peut pas changer l'ordre entre les différents CTE.

J'espère que cela aide :)

cohenjo
la source