Änderung an GEQO (Genetic Query Optimization) von PostgreSQL

16

Ich muss eine Funktionalität implementieren, die der GEQO-Funktionalität von PostgreSQL entspricht. Ich verstehe, dass der GEQO-Ansatz darin besteht, Abfragepläne als Ganzzahlzeichenfolgen zu codieren, und GEQO generiert diese möglichen Verknüpfungssequenzen nach dem Zufallsprinzip. Quelle: http://www.postgresql.org/docs/9.3/static/geqo-pg-intro.html

Meine Frage: Wie ändere ich die GEQO-Funktion, wenn ich die richtige Verknüpfungssequenz definitiv kenne, damit ich nicht nach verschiedenen Verknüpfungssequenzen suchen muss? Wenn ich zum Beispiel wüsste, dass der beste Weg, die 4 Relationen zu verbinden, 4-1-3-2 ist, muss ich nicht nach anderen Permutationen suchen.

Es gibt keine guten Materialien zur Implementierung von GEQO in PostgreSQL. PostgreSQL gibt nur einen Überblick über die GEQO-Funktionalität, erklärt aber nicht viel.

Oder könnte ich diese Funktionalität in der standard_join_search () selbst erreichen, ohne GEQO zu verwenden?

user2761431
quelle
3
Es hört sich so an, als ob Sie Abfragehinweise implementieren möchten. Das ist alles in Ordnung und gut, aber Sie sollten nicht damit rechnen, dass die Änderung in PostgreSQL Core akzeptiert wird, da die Projekt-Community kein großer Fan von Abfragetipps ist. Wenn Sie das ernst meinen, müssen Sie eine ganze Menge des Abfrageplaner-Codes lesen und herausfinden, wie Sie Ihre Hinweise vom Parser über den Rewriter in den Planer weitergeben können. Ich sehe hier keine schnelle und einfache Antwort. Sie möchten schließlich eine bestimmte Pfadauswahl im Planer / Optimierer erzwingen.
Craig Ringer
Ah, ja, sie sind skeptisch in Bezug auf Fragen. Ich habe den Planercode gelesen und es schien, als wäre GEQO eine Möglichkeit, die Änderungen am vorhandenen Kern zu minimieren.
user2761431
2
Ist es das, was Sie erreichen wollen, um Abfragetipps zu implementieren, um die Reihenfolge der Joins zu erzwingen? Wenn ja, prüfen Sie, ob dies bereits von anderen implementiert wurde. Sie sollten sich auch überlegen, warum Sie es brauchen, warum der Planer überhaupt die falschen Entscheidungen trifft. Erwägen Sie, einen in sich geschlossenen Testfall zu erstellen und an pgsql-performance zu berichten.
Craig Ringer
3
Es gibt pg_hint_plan : en.sourceforge.jp/projects/pghintplan , aber ich habe es nicht benutzt. Eine DBA teilte mir mit, dass es am 9.2 funktioniere. Es gibt auch Artikel in russischer Sprache darüber habrahabr.ru/post/169751
ckorzhik

Antworten:

1

Eine Möglichkeit, dies zu tun, ohne sich mit GEKO herumschlagen zu müssen, ist die Verwendung von CTE.

CTE sind Optimierungsbarrieren, daher können Sie die Joins in CTEs in der von Ihnen gewünschten Reihenfolge einbinden, und PG wird dazu gezwungen.

Wenn wir zum Beispiel den DB zwingen wollen, zuerst t1 mit t2 zu verbinden und erst dann mit t4 könnten wir so etwas ausführen:

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;

Dies führt zu:

                                  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)

Dies ist nur ein Beispiel, Sie können es nach Bedarf ändern. In jedem Fall kann PG die Reihenfolge zwischen den verschiedenen CTEs nicht ändern.

Ich hoffe es hilft :)

cohenjo
quelle