Re: Add semi-join pushdown to postgres_fdw - Mailing list pgsql-hackers
From | Alexander Korotkov |
---|---|
Subject | Re: Add semi-join pushdown to postgres_fdw |
Date | |
Msg-id | CAPpHfdtnBO87ryw3cZ148y3XAjjTYmS+a0Nin9qTY9guRiU_Uw@mail.gmail.com Whole thread Raw |
In response to | Re: Add semi-join pushdown to postgres_fdw (Pavel Luzanov <p.luzanov@postgrespro.ru>) |
List | pgsql-hackers |
On Fri, Feb 9, 2024 at 10:08 PM Pavel Luzanov <p.luzanov@postgrespro.ru> wrote: > While playing with this feature I found the following. > > Two foreign tables: > postgres@demo_postgres_fdw(17.0)=# \det aircrafts|seats > List of foreign tables > Schema | Table | Server > --------+-----------+------------- > public | aircrafts | demo_server > public | seats | demo_server > (2 rows) > > > This query uses optimization: > > postgres@demo_postgres_fdw(17.0)=# EXPLAIN (costs off, verbose) SELECT * > FROM aircrafts a > WHERE a.aircraft_code = '320' AND EXISTS ( > SELECT * FROM seats s WHERE s.aircraft_code = a.aircraft_code > ); > QUERY PLAN > > --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------> > Foreign Scan > Output: a.aircraft_code, a.model, a.range > Relations: (public.aircrafts a) SEMI JOIN (public.seats s) > Remote SQL: SELECT r1.aircraft_code, r1.model, r1.range FROM bookings.aircrafts r1 WHERE ((r1.aircraft_code = '320'))AND EXISTS (SELECT NULL FROM bookings.seats r2 WHERE ((r2.aircraft_code => > (4 rows) > > > But optimization not used for NOT EXISTS: > > postgres@demo_postgres_fdw(17.0)=# EXPLAIN (costs off, verbose) SELECT * > FROM aircrafts a > WHERE a.aircraft_code = '320' AND NOT EXISTS ( > SELECT * FROM seats s WHERE s.aircraft_code = a.aircraft_code > ); > QUERY PLAN > ---------------------------------------------------------------------------------------------------------------- > Nested Loop Anti Join > Output: a.aircraft_code, a.model, a.range > -> Foreign Scan on public.aircrafts a > Output: a.aircraft_code, a.model, a.range > Remote SQL: SELECT aircraft_code, model, range FROM bookings.aircrafts WHERE ((aircraft_code = '320')) > -> Materialize > Output: s.aircraft_code > -> Foreign Scan on public.seats s > Output: s.aircraft_code > Remote SQL: SELECT aircraft_code FROM bookings.seats WHERE ((aircraft_code = '320')) > (10 rows) > > Also, optimization not used after deleting first condition (a.aircraft_code = '320'): > > postgres@demo_postgres_fdw(17.0)=# EXPLAIN (costs off, verbose) SELECT * > FROM aircrafts a > WHERE EXISTS ( > SELECT * FROM seats s WHERE s.aircraft_code = a.aircraft_code > ); > QUERY PLAN > -------------------------------------------------------------------------------- > Hash Join > Output: a.aircraft_code, a.model, a.range > Inner Unique: true > Hash Cond: (a.aircraft_code = s.aircraft_code) > -> Foreign Scan on public.aircrafts a > Output: a.aircraft_code, a.model, a.range > Remote SQL: SELECT aircraft_code, model, range FROM bookings.aircrafts > -> Hash > Output: s.aircraft_code > -> HashAggregate > Output: s.aircraft_code > Group Key: s.aircraft_code > -> Foreign Scan on public.seats s > Output: s.aircraft_code > Remote SQL: SELECT aircraft_code FROM bookings.seats > (15 rows) > > > But the worst thing is that replacing AND with OR causes breaking session and server restart: > > postgres@demo_postgres_fdw(17.0)=# EXPLAIN (costs off, verbose) SELECT * > FROM aircrafts a > WHERE a.aircraft_code = '320' OR EXISTS ( > SELECT * FROM seats s WHERE s.aircraft_code = a.aircraft_code > ); > server closed the connection unexpectedly > This probably means the server terminated abnormally > before or while processing the request. > The connection to the server was lost. Attempting reset: Failed. > The connection to the server was lost. Attempting reset: Failed. Thank you, Pavel. I'm looking into this. ------ Regards, Alexander Korotkov
pgsql-hackers by date: