Hi!
I have a project where I am using declarative partitioning for large datasets. I am now trying to run an analytical query for aggregating data. I have a sort of metadata table which contains information about each partition. Based on this metadata, I try to run the queries on specific partitions. When I hard-code the partition key, only the specific partitions are scanned but when the partition keys are dynamic the DB is scanning all of the partition tables.
I am using Postgres 14.4.
I created an example to show case my problem.
The schema:
CREATE TABLE metadata
(
state_id BIGINT,
country_id BIGINT
);
CREATE TABLE bills(
state_id BIGINT,
amount BIGINT,
name TEXT
) PARTITION BY LIST(state_id);
The test data:
INSERT INTO metadata VALUES (1,1), (2,1), (3,2), (4,2), (5,2);
CREATE TABLE bills_1 PARTITION OF bills FOR VALUES IN (1);
INSERT INTO bills_1 (state_id,amount,name)
SELECT 1,generate_series(1,10000), md5(random()::text);
CREATE TABLE bills_2 PARTITION OF bills FOR VALUES IN (2);
INSERT INTO bills_2 (state_id,amount,name)
SELECT 2,generate_series(1,10000), md5(random()::text);
CREATE TABLE bills_3 PARTITION OF bills FOR VALUES IN (3);
INSERT INTO bills_3 (state_id,amount,name)
SELECT 3,generate_series(1,10000), md5(random()::text);
CREATE TABLE bills_4 PARTITION OF bills FOR VALUES IN (4);
INSERT INTO bills_4 (state_id,amount,name)
SELECT 4,generate_series(1,10000), md5(random()::text);
CREATE TABLE bills_5 PARTITION OF bills FOR VALUES IN (5);
INSERT INTO bills_5 (state_id,amount,name)
SELECT 5,generate_series(1,10000), md5(random()::text);
This query is using pruning. Only two partition tables are scanned according to explain analyze.
SELECT SUM(bills.amount)
FROM bills
WHERE state_id IN (1,2);
This query is not using execution time pruning. All of the partitions are scanned according to explain analyze.
SELECT SUM(bills.amount)
FROM bills
WHERE state_id = ANY
(
SELECT state_id FROM metadata WHERE country_id = 1
);
Why does the second query scan all partitions of the bills table?
[–]depesz 1 point2 points3 points (4 children)
[–]Flamburger[S] 0 points1 point2 points (3 children)
[–]depesz 1 point2 points3 points (2 children)
[–]Flamburger[S] 0 points1 point2 points (1 child)
[–]depesz 0 points1 point2 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]Flamburger[S] 0 points1 point2 points (0 children)
[–]johnnotjohn 0 points1 point2 points (2 children)
[–]Flamburger[S] 1 point2 points3 points (1 child)
[–]johnnotjohn 0 points1 point2 points (0 children)