Reputation: 25113
I have two pretty similar queries:
WITH USAGE AS NOT MATERIALIZED ( SELECT
ocd.*,
1 AS conf_suma
FROM(
SELECT o, o.agreement_id AS agreement_id
FROM "order_bt" o
WHERE o.sys_period @> sys_time()
AND (o.app_period && tstzrange( '2021-01-01', '2021-02-01' ))
)ocd
)
SELECT
*,
(conf_suma/6) ::numeric( 10, 2 ) as group_nds,
(SELECT sum(conf_suma) from USAGE sq WHERE sq.agreement_id = agreement_id) as total_suma -- #1 SLOW
-- #2 FAST: (SELECT sum(conf_suma) from USAGE sq WHERE sq.agreement_id = 3385) as total_suma
FROM USAGE
WHERE agreement_id = 3385 -- LAST WHERE
They are differ only by this part sq.agreement_id = agreement_id
VS sq.agreement_id = 3385
Plan for them are #1 slow and #2 fast
Why optimization is not applied at first case? To my mind optimizer could see from LAST WHERE
that there is only one agreement_id
. So agreement_id
is like constant. If we fold this constant into slow
subquery it becomes same as fast
subquery. Is this place for planner improvement?
PS. At one my query on production this cause query to run 12sec instead of 20ms
Upvotes: 2
Views: 55
Reputation: 25113
Thanks to RhodiumToad at IRC. Mistake was at agreement_id
name.
It must be written as usage.agreement_id
:
(SELECT sum(conf_suma) from USAGE sq WHERE sq.agreement_id = usage.agreement_id) as total_suma -- #1 NOW IT IS FAST TOO
Now plan fine. As expected by me:
Upvotes: 2
Reputation: 24568
because the slow query , aggregation function runs for all the rows that meet condition sq.agreement_id = agreement_id
which is 1346 rows and then you filter the result of subquery
while the fast query you filter the result right off the bat and subquery only returns 4 rows thus only aggregation only runs for 4 rows.
also If you look at index condition for #4 Bitmap Index Scan , because of your condition sql optimizer has to look up these conditions :
((o_1.sys_period @> sys_time())
AND (o_1.app_period && '["2021-01-01 00:00:00+02","2021-02-01 00:00:00+02")'::tstzrange))
while in the fast query , index condition is
(o_1.agreement_id = 3385)
so those conditions in the slow query are postponed to #3 Bitmap Heap Scan
which only applies to 4 rows for fast query.
Upvotes: 0