In earlier PostgreSQL versions, it was not possible to declare table partitions syntactically. Partitioning can be implemented using table inheritance. The inheritance approach involves creating a single parent table and multiple child tables (aka. Partitions) to hold data in each partition range.
In this post, I’ll discuss the implementation of table partitions using inheritance. However before proceeding, let’s first understand why do we need partitioning?
Why Partition?
The simple answer is to improve the scalability and manageability of large data sets and tables that have varying access patterns.
Typically, you create tables to store information about an entity, such as customers or sales, and each table has attributes that describe only that entity. While a single table for each entity is the easiest to design and understand, these tables are not necessarily optimized for performance, scalability, and manageability, particularly as the table grows larger.
How can partitioning help?
- When tables and indexes become very large, partitioning can help by partitioning the data into smaller and more manageable sections.
- It allows you to speed up loading and archiving of data, so that you can perform maintenance operations on individual partitions instead of the whole table, and this in turn improves the query performance.
There is a ton of information published on partitioning, But if you new to partitioning in PostgreSQL, below are some great examples:
- PostgreSQL documentation – https://www.postgresql.org/docs/10/ddl-partitioning.html#DDL-PARTITIONING-IMPLEMENTATION-INHERITANCE
- Heroku Blogs – https://blog.heroku.com/handling-very-large-tables-in-postgres-using-partitioning
Now that we have some insight what table partitioning is, let’s do a real partitioning using below scripts:
How to Partition a Table?
— Step 1.
— CREATE PARENT & CHILD TABLES
CREATE TABLE parent (
id int,
col_a varchar,
col_b varchar);
--Child Table 1
CREATE TABLE range1() INHERITS (parent);
--Child Table 2
CREATE TABLE range2() INHERITS (parent);
--Child Table 3
CREATE TABLE range3() INHERITS (parent);
Let’s review the schema now
— Step 2.
— CREATE PARTITION FUNCTION THAT WILL HOLD LOGIC OF ‘ON-INSERT’ TRIGGER
CREATE OR REPLACE FUNCTION partition_parent() RETURNS trigger as $$
BEGIN
IF (new.id < 10) THEN
INSERT INTO range1 VALUES (new.*) ;
ELSEIF (new.id >= 10 AND NEW.id < 20 ) then
INSERT INTO range2 VALUES (new.*) ;
ELSEIF (new.id >= 20 AND NEW.id < 30 ) then
INSERT INTO range3 VALUES (new.*) ;
ELSE
RAISE EXCEPTION 'out of range';
END IF;
RETURN NULL;
END;
$$ language plpgsql;
— Step 3.
— CREATE TRIGGER AND ATTACH IT TO THE PARENT TABLE TO BE PARTITIONED
CREATE TRIGGER partition_parent_trigger
BEFORE INSERT ON parent
FOR EACH ROW EXECUTE PROCEDURE partition_parent();for each row execute PROCEDURE partition_parent();
— Step 4.
— INSERT SAMPLE ROWS
DO $$DECLARE
BEGIN
FOR i in 1..29 LOOP
INSERT INTO parent(id, col_a, col_b) VALUES (i, 'a', 'b');
END LOOP;
END $$;
— Optional Step (stats update)
ANALYZE parent;
-- Step 5.
-- TEST PARTITION ELIMINATION (PRUNING)
EXPLAIN ANALYZE
SELECT * from parent
WHERE id = 5;
Query Plan
In the next Post in this series, I’ll discuss the new ‘Declarative Partitioning‘ implementation
thanks for reading!



2 thoughts on “PostgreSQL Table Partitioning Part I – Implementation Using Inheritance”