Modyfikacja do GEQO (Optymalizacja zapytań genetycznych) PostgreSQL

16

Muszę wdrożyć funkcjonalność zgodną z funkcjonalnością GEQO PostgreSQL. Rozumiem, że podejście GEQO polega na kodowaniu planów zapytań jako ciągów liczb całkowitych, a GEQO generuje te możliwe sekwencje łączenia losowo. Źródło: http://www.postgresql.org/docs/9.3/static/geqo-pg-intro.html

Moje pytanie: jak zmodyfikować funkcję GEQO, jeśli definitywnie znam właściwą sekwencję łączenia, aby nie musiałem wyszukiwać różnych sekwencji łączenia. Na przykład, gdybym wiedział, że najlepszym sposobem na połączenie 4 relacji jest 4-1-3-2, nie muszę sprawdzać innych permutacji.

Nie ma żadnych dobrych materiałów na temat implementacji GEQO w PostgreSQL. PostgreSQL daje jedynie ogólny obraz funkcjonalności GEQO, ale niewiele wyjaśnia.

Czy mogę osiągnąć tę funkcjonalność w samym standardzie_join_search () bez korzystania z GEQO?

użytkownik2761431
źródło
3
Wygląda na to, że chcesz wdrożyć wskazówki dotyczące zapytań. To wszystko dobrze i dobrze, ale nie powinieneś oczekiwać, że zmiana zostanie zaakceptowana w rdzeniu PostgreSQL, ponieważ społeczność projektowa nie jest tym, co nazwałbyś wielkim fanem wskazówek dotyczących zapytań. Jeśli poważnie podchodzisz do tego, musisz przeczytać sporo kodu terminarza zapytań i musisz dowiedzieć się, jak przekazać wskazówki od parsera przez program do pisania i do terminarza. Nie widzę tutaj szybkiej i prostej odpowiedzi. To, co ostatecznie chcesz zrobić, to wymusić wybór określonej ścieżki w narzędziu do planowania / optymalizacji.
Craig Ringer
Ach, tak, są sceptycznie nastawieni do wskazówek dotyczących zapytań. Przeczytałem kod planisty i wydawało się, że GEQO będzie sposobem na zminimalizowanie zmian w istniejącym rdzeniu.
user2761431
2
Czy to właśnie próbujesz osiągnąć, aby zaimplementować wskazówki dotyczące zapytań, aby wymusić zamówienie dołączania? Jeśli tak, sprawdź, czy ktoś już go wdrożył. Powinieneś także rozważyć, dlaczego go potrzebujesz, dlaczego planista dokonuje niewłaściwych wyborów. Zastanów się nad stworzeniem niezależnego przypadku testowego i raportowaniem do pgsql-performance.
Craig Ringer
3
Istnieje pg_hint_plan : en.sourceforge.jp/projects/pghintplan , ale go nie użyłem . Jeden dba powiedział mi, że działa na 9.2. Jest też artykuł w języku rosyjskim na ten temat habrahabr.ru/post/169751
ckorzhik

Odpowiedzi:

1

Jednym ze sposobów, w jaki możesz to zrobić bez potrzeby manipulowania GEKO, jest użycie CTE.

CTE to bariery optymalizacyjne, dlatego można łączyć połączenia wewnątrz CTE w żądanej kolejności, a PG będzie zmuszony to zrobić.

Na przykład, jeśli chcemy zmusić DB do pierwszego połączenia t1 z t2, a dopiero potem z t4 możemy uruchomić coś takiego:

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;

Spowoduje to:

                                  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)

To tylko przykład, możesz go zmienić w razie potrzeby - w każdym razie PG nie może zmienić kolejności między różnymi CTE.

Mam nadzieję, że to pomoże :)

cohenjo
źródło