Starting Postgres 10.x and onward, it is now possible to create declarative partitions.
In my previous post ‘postgresql-table-partitioning-part-i-implementation-using-inheritance‘, I discussed about implementing Partitioning in PostgreSQL using ‘Inheritance’. Up until PostgreSQL 9, it was only way to partition tables in PostgreSQL. It was simple to implement, however had some limitations like:
- Row INSERT does not automatically propagate data to a child tables (aka partition), instead it uses explicit ‘BEFORE INSERT’ trigger, making them slower
- INDEXES and constraints have to be separately created on child tables
- Significant manual work is required to create and maintain child tables ranges
‘Declarative’ partitioning released with Postgres 10 does not have these limitations and requires much less manual work to manage partitions.
Let’s see the implementation of ‘Declarative’ partitioning with example:
— Step 1.
— Create a partitioned table using the PARTITION BY clause, — which includes the partitioning method (RANGE in this example) and the list of column(s) to use as the partition key
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
) PARTITION BY RANGE (logdate);
— Step 2.
— Create Index on parent table
— Note: creation of seperate indexes on parent table is not required
CREATE INDEX measurement_indx_logdate ON measurement (logdate);
— Step 3.
— Create Default partition
CREATE TABLE measurement_default PARTITION OF measurement DEFAULT;
— Create partitions with exclusive range and dfeualt partition (catch-all for out of range values)
CREATE TABLE measurement_y2006m02 PARTITION OF measurement FOR VALUES FROM ('2006-02-01') TO ('2006-03-01'); CREATE TABLE measurement_y2006m03 PARTITION OF measurement FOR VALUES FROM ('2006-03-01') TO ('2006-04-01'); CREATE TABLE measurement_y2006m04 PARTITION OF measurement FOR VALUES FROM ('2006-04-01') TO ('2006-05-01'); CREATE TABLE measurement_y2007m11 PARTITION OF measurement FOR VALUES FROM ('2007-11-01') TO ('2007-12-01');
Let’s review our schema now
— Step 4
— Insert sample rows
DO $DECLARE BEGIN FOR i in 1..10 loop INSERT INTO measurement VALUES (1,'2006-02-07',1,1); end loop; end $; DO $DECLARE BEGIN FOR i in 1..1000000 loop INSERT INTO measurement VALUES (1,'2006-03-06',1,1); end loop; end $; DO $DECLARE BEGIN FOR i in 1..1000000 loop INSERT INTO measurement VALUES (1,'2006-04-09',1,1); end loop; end $; DO $DECLARE BEGIN FOR i in 1..1000000 loop INSERT INTO measurement VALUES (1,'2007-11-11',1,1); end loop; end $; --Optional Step ANALYZE measurement;
–Step 5
–Test partition elimination
SELECT * FROM measurement WHERE logdate = '2007-11-11';
Let’s look at the Query Plan
As you can see, the ‘Declarative’ partitioning is much more intuitive and requires less manual steps in declaring partitions compares to inheritance.
thanks for reading!



2 thoughts on “PostgreSQL Table Partitioning Part II – Declarative Partitioning”