Sample Header Ad - 728x90

PostgreSQL partition pruning problem

0 votes
1 answer
326 views
Let us suppose that I have a table d_day containing two columns, id_day, and date, and a table fact that contains two columns, id_day and fact. My table fact is partitioned across id_day. The request
SELECT * FROM fact
WHERE "ID_DAY" between  and
is pruning partitions properly, and is almost instant but
SELECT * FROM fact
INNER JOIN d_dat USING (id_day)
WHERE date between  and
is not. I have a UNIQUE constraint over date in my d_day column. So, I have a 1:1 relationship between the two columns. On a broader level, I do not understand how the query planner deals with this demand. Even something like :
SELECT * FROM fact
WHERE id_day IN (
   SELECT DISTINCT(id_day) WHERE date BETWEEN  and 
)
is slow. Here is a practical example when filtering on DATEJ:
set enable_partitionwise_join = true; set enable_partitionwise_aggregate = true;
EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)(
select * from "F_TDOJ_HIST_2" fth
inner join "D_TRAIN" dt using ("ID_TRAIN")
inner join "DL_CAPTURE_DATE" dj using ("ID_JOUR", "JX")
where "JX" = -72 
and "ID_ENTNAT" between 4000 and 4999
and "DATEJ" = '2023-12-08'::date);
(Explain analyze ) And here is the example when filtering on ID_JOUR
set enable_partitionwise_join = true; set enable_partitionwise_aggregate = true;
EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)(
select * from "F_TDOJ_HIST_2" fth
inner join "D_TRAIN" dt using ("ID_TRAIN")
inner join "DL_CAPTURE_DATE" dj using ("ID_JOUR", "JX")
where "JX" = -72 
and "ID_ENTNAT" between 4000 and 4999
and "ID_JOUR" = 4756);
(Explain analyze ) Also, when I play the request using DATEJ on a copy of my database, partitioned across a different ID_JOUR span (30 ID_JOUR in a partition vs 3 ID_JOUR) now, I get this plan, which is **much faster**, so I know doing something is possible. I just do not understand why it is now slower, what to change, and why :
set enable_partitionwise_join = true; set enable_partitionwise_aggregate = true;
EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)(
select * from "F_TDOJ_HIST_2" fth
inner join "D_TRAIN" dt using ("ID_TRAIN")
inner join "DL_CAPTURE_DATE" dj using ("ID_JOUR", "JX")
where "JX" = -72 
and "ID_ENTNAT" between 4000 and 4999
and "DATEJ" = '2023-12-08'::date);
(Explain analyze )
Asked by Doe Jowns (141 rep)
Oct 19, 2023, 02:19 PM
Last activity: May 9, 2025, 08:02 AM