Background story :
I'm working on a query with a lot of left joins (doctrine joined inheritance on an old project).
The query is run against a 9.4 postgres & its structure (lightened) looks like this :
SELECT *
FROM table1 a0_
LEFT JOIN table2 a1_ ON a0_.id = a1_.id
LEFT JOIN table3 a2_ ON a0_.id = a2_.id
WHERE a0_.created_at <= '2019-11-25 15:09:33' LIMIT 5
This query is slowed down by the limit (on the original huge query) because, from my understanding, it first joins on all tables before performing the limit.
I already figured out a way to fix this behavior by moving where & limit in a subquery acting as source table, thus reducing original data pool (improving performance by around 4).
Problem faced :
In order to fully understand what happened behind, I analyzed the original query, which outputs this (you can also get a beautified view here) :
Limit (cost=0.42..24.49 rows=1 width=10536) (actual time=0.129..0.546 rows=5 loops=1)
-> Nested Loop Left Join (cost=0.42..24.49 rows=1 width=10536) (actual time=0.113..0.462 rows=5 loops=1)
-> Nested Loop Left Join (cost=0.27..16.31 rows=1 width=9976) (actual time=0.071..0.285 rows=5 loops=1)
-> Index Scan using table1_pkey on table1 a0_ (cost=0.12..8.14 rows=1 width=9428) (actual time=0.022..0.063 rows=5 loops=1)
Filter: (created_at <= '2019-11-25 15:09:33'::timestamp without time zone)
-> Index Scan using table2_pkey on table2 a1_ (cost=0.14..8.16 rows=1 width=548) (actual time=0.012..0.015 rows=1 loops=5)
Index Cond: ((a0_.id)::text = (id)::text)
-> Index Scan using table3_pkey on table3 a2_ (cost=0.14..8.16 rows=1 width=560) (actual time=0.010..0.010 rows=0 loops=5)
Index Cond: ((a0_.id)::text = (id)::text)
On the new optimized query (with where & limit in subquery), the explain shows the limit being made right after the where filter.
What I don't understand on this original query's explain is that despite limit being "runned" last, it seems to already be active on the first statement run which only outputs 5 rows (against 8 without limit).
Could someone explain why ?