SlideShare a Scribd company logo
1 of 24
Download to read offline
Table Partitioning
PostgreSQL + Rails
Agnieszka Figiel, Cambridge Ruby User Group Mar 2014
What is table partitioning in
PostgreSQL?
1 logical table = n smaller physical tables
What are the benefits?
improved query performance for big tables *
* works best when results are coming from
single partition
When to consider partitioning?
Big table that cannot be queried efficiently, as
the index is enormous as well.
Rule of thumb: table does not fit into memory
How is data split?
By ranges:
year > 2010 AND year <= 2012
By lists of key values:
company_id = 5
How does it work?
At the heart of it lie 2 mechanisms:
➔ table inheritance
➔ table CHECK constraints
Table inheritance: schema
CREATE TABLE A (value INT);
CREATE TABLE B () INHERITS (A);
Table "public.a"
Column | Type | Modifiers
--------+---------+-----------
value | integer |
Table "public.b"
Column | Type | Modifiers
--------+---------+-----------
value | integer |
Inherits: a
Table inheritance: schema
CREATE TABLE C (extra_field TEXT) INHERITS (A);
Table "public.c"
Column | Type | Modifiers
-------------+---------+-----------
value | integer |
extra_field | text |
Inherits: a
NB: may inherit from multiple tables
Table inheritance: querying
INSERT INTO A VALUES (0);
INSERT INTO B VALUES (10);
INSERT INTO C VALUES (20, 'zonk');
SELECT * FROM A WHERE value < 20;
value
-------
0
10
SELECT * FROM ONLY A WHERE value < 20;
value
-------
0
What happened?
EXPLAIN ANALYZE SELECT * FROM A WHERE value < 20;
QUERY PLAN
----------------------------------------------------------------------------------------------------
Append (cost=0.00..69.38 rows=1290 width=4) (actual time=0.020..0.033 rows=2 loops=1)
-> Seq Scan on a (cost=0.00..4.00 rows=80 width=4) (actual time=0.019..0.021 rows=1 loops=1)
Filter: (value < 20)
-> Seq Scan on b (cost=0.00..40.00 rows=800 width=4) (actual time=0.005..0.006 rows=1 loops=1)
Filter: (value < 20)
-> Seq Scan on c (cost=0.00..25.38 rows=410 width=4) (actual time=0.005..0.005 rows=0 loops=1)
Filter: (value < 20)
Rows Removed by Filter: 1
Table CHECK constraint
CREATE TABLE A (value INT);
CREATE TABLE B (CHECK (value < 20)) INHERITS (A);
CREATE TABLE C (CHECK (value >= 20)) INHERITS (A);
INSERT INTO B VALUES (10);
INSERT INTO C VALUES (20);
INSERT INTO C VALUES(5);
ERROR: new row for relation "c" violates check constraint "c_value_check"
DETAIL: Failing row contains (5).
Ta da!
EXPLAIN ANALYZE SELECT * FROM A WHERE value < 20;
QUERY PLAN
----------------------------------------------------------------------------------------------------
Append (cost=0.00..40.00 rows=801 width=4) (actual time=0.015..0.017 rows=1 loops=1)
-> Seq Scan on a (cost=0.00..0.00 rows=1 width=4) (actual time=0.002..0.002 rows=0 loops=1)
Filter: (value < 20)
-> Seq Scan on b (cost=0.00..40.00 rows=800 width=4) (actual time=0.012..0.013 rows=1 loops=1)
Filter: (value < 20)
Gotcha #1
Make sure that:
SET constraint_exclusion = on;
Gotcha #2
All check constraints and not-null constraints on a parent table are
automatically inherited by its children.
Other types of constraints (unique, primary key, and foreign key constraints)
are not inherited.
Solution #2: create constraints or
indexes in all partitions
CREATE TABLE A (id serial NOT NULL, value INT NOT NULL);
CREATE TABLE B (
CONSTRAINT B_pkey PRIMARY KEY (id),
CHECK (value < 20)
) INHERITS (A);
CREATE TABLE C (
CONSTRAINT C_pkey PRIMARY KEY (id),
CHECK (value >= 20)
) INHERITS (A);
Gotcha #3
There is no practical way to enforce uniqueness of a SERIAL id across
partitions.
INSERT INTO B (value) VALUES (10);
INSERT INTO C (value) VALUES (20);
INSERT INTO C VALUES (1, 30);
SELECT * FROM A;
id | value
----+-------
1 | 10
2 | 20
1 | 30
Solution #3
➔ carry on and always filter by partitioning key
➔ use UUID (uuid-ossp)
Gotcha #4
Specifying that another table's column REFERENCES a(value) would allow the
other table to contain “a values”, but not “b or c values”. There is no good
workaround for this case.
How to insert / update rows?
➔ PostgreSQL docs recommend using triggers
➔ also possible to do it using rules (overhead, bulk)
Trigger example
CREATE OR REPLACE FUNCTION a_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.value < 20 THEN
INSERT INTO b VALUES (NEW.*);
ELSE
INSERT INTO c VALUES (NEW.*);
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER insert_a_trigger
BEFORE INSERT ON a
FOR EACH ROW EXECUTE PROCEDURE a_insert_trigger();
Partitioned gem
https://github.com/fiksu/partitioned
class Company < ActiveRecord::Base; end
class ByCompanyId < Partitioned::ByForeignKey
self.abstract_class = true
belongs_to :company
def self.partition_foreign_key
return :company_id
end
partitioned do |partition|
partition.index :id, :unique => true
end
end
class Employee < ByCompanyId; end
employee = Employee.from_partition(1).find(1)
UUID in Rails
Rails 4:
enable_extension 'uuid-ossp'
create_table :documents, id: :uuid do |t|
t.string :title
t.string :author
t.timestamps
end
Rails 3:
gem postgres_ext https://github.com/dockyard/postgres_ext
Actual performance improvements?
➔ table with ~13 mln rows
➔ partitioned by date into 8 partitions
➔ complex, long-running query
➔ baseline: 0.07 tps
➔ when results in single partition: 0.15 tps
➔ when results in 2 partitions: like baseline
References
➔ http://www.postgresql.org/docs/9.3/static/ddl-
partitioning.html
➔ PostgreSQL 9.0 High Performance Gregory Smith

More Related Content

What's hot

What's hot (20)

PostgreSql query planning and tuning
PostgreSql query planning and tuningPostgreSql query planning and tuning
PostgreSql query planning and tuning
 
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
 
10 Good Reasons to Use ClickHouse
10 Good Reasons to Use ClickHouse10 Good Reasons to Use ClickHouse
10 Good Reasons to Use ClickHouse
 
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEOClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
 
Sql query patterns, optimized
Sql query patterns, optimizedSql query patterns, optimized
Sql query patterns, optimized
 
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
 
PostgreSQL Performance Tables Partitioning vs. Aggregated Data Tables
PostgreSQL Performance Tables Partitioning vs. Aggregated Data TablesPostgreSQL Performance Tables Partitioning vs. Aggregated Data Tables
PostgreSQL Performance Tables Partitioning vs. Aggregated Data Tables
 
Introduction to redis
Introduction to redisIntroduction to redis
Introduction to redis
 
Real-time Data Ingestion from Kafka to ClickHouse with Deterministic Re-tries...
Real-time Data Ingestion from Kafka to ClickHouse with Deterministic Re-tries...Real-time Data Ingestion from Kafka to ClickHouse with Deterministic Re-tries...
Real-time Data Ingestion from Kafka to ClickHouse with Deterministic Re-tries...
 
Altinity Quickstart for ClickHouse
Altinity Quickstart for ClickHouseAltinity Quickstart for ClickHouse
Altinity Quickstart for ClickHouse
 
ClickHouse Monitoring 101: What to monitor and how
ClickHouse Monitoring 101: What to monitor and howClickHouse Monitoring 101: What to monitor and how
ClickHouse Monitoring 101: What to monitor and how
 
Building ClickHouse and Making Your First Contribution: A Tutorial_06.10.2021
Building ClickHouse and Making Your First Contribution: A Tutorial_06.10.2021Building ClickHouse and Making Your First Contribution: A Tutorial_06.10.2021
Building ClickHouse and Making Your First Contribution: A Tutorial_06.10.2021
 
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
 
PostgreSQL Database Slides
PostgreSQL Database SlidesPostgreSQL Database Slides
PostgreSQL Database Slides
 
Introduction to the Mysteries of ClickHouse Replication, By Robert Hodges and...
Introduction to the Mysteries of ClickHouse Replication, By Robert Hodges and...Introduction to the Mysteries of ClickHouse Replication, By Robert Hodges and...
Introduction to the Mysteries of ClickHouse Replication, By Robert Hodges and...
 
PostgreSQL: Advanced indexing
PostgreSQL: Advanced indexingPostgreSQL: Advanced indexing
PostgreSQL: Advanced indexing
 
Data Warehouses in Kubernetes Visualized: the ClickHouse Kubernetes Operator UI
Data Warehouses in Kubernetes Visualized: the ClickHouse Kubernetes Operator UIData Warehouses in Kubernetes Visualized: the ClickHouse Kubernetes Operator UI
Data Warehouses in Kubernetes Visualized: the ClickHouse Kubernetes Operator UI
 
Data Warehouse on Kubernetes: lessons from Clickhouse Operator
Data Warehouse on Kubernetes: lessons from Clickhouse OperatorData Warehouse on Kubernetes: lessons from Clickhouse Operator
Data Warehouse on Kubernetes: lessons from Clickhouse Operator
 
MySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxMySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptx
 
ClickHouse Introduction by Alexander Zaitsev, Altinity CTO
ClickHouse Introduction by Alexander Zaitsev, Altinity CTOClickHouse Introduction by Alexander Zaitsev, Altinity CTO
ClickHouse Introduction by Alexander Zaitsev, Altinity CTO
 

Similar to Table partitioning in PostgreSQL + Rails

Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007
paulguerin
 
DDL,DML,SQL Functions and Joins
DDL,DML,SQL Functions and JoinsDDL,DML,SQL Functions and Joins
DDL,DML,SQL Functions and Joins
Ashwin Dinoriya
 
Entity Attribute Value (Eav)
Entity   Attribute   Value (Eav)Entity   Attribute   Value (Eav)
Entity Attribute Value (Eav)
Tâm
 

Similar to Table partitioning in PostgreSQL + Rails (20)

Less08 Schema
Less08 SchemaLess08 Schema
Less08 Schema
 
MySQL 8.0 NF : Common Table Expressions (CTE)
MySQL 8.0 NF : Common Table Expressions (CTE)MySQL 8.0 NF : Common Table Expressions (CTE)
MySQL 8.0 NF : Common Table Expressions (CTE)
 
Tableau + Redshift views for dummies
Tableau + Redshift views for dummiesTableau + Redshift views for dummies
Tableau + Redshift views for dummies
 
Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007
 
Preparing for BIT – IT2301 Database Management Systems 2001f
Preparing for BIT – IT2301 Database Management Systems 2001fPreparing for BIT – IT2301 Database Management Systems 2001f
Preparing for BIT – IT2301 Database Management Systems 2001f
 
Optimizer features in recent releases of other databases
Optimizer features in recent releases of other databasesOptimizer features in recent releases of other databases
Optimizer features in recent releases of other databases
 
chapter 8 SQL.ppt
chapter 8 SQL.pptchapter 8 SQL.ppt
chapter 8 SQL.ppt
 
Chapter 07 ddl_sql
Chapter 07 ddl_sqlChapter 07 ddl_sql
Chapter 07 ddl_sql
 
Sql wksht-2
Sql wksht-2Sql wksht-2
Sql wksht-2
 
Mysql
MysqlMysql
Mysql
 
Mysql
MysqlMysql
Mysql
 
Mysql
MysqlMysql
Mysql
 
Db1 lecture4
Db1 lecture4Db1 lecture4
Db1 lecture4
 
Optimizing queries MySQL
Optimizing queries MySQLOptimizing queries MySQL
Optimizing queries MySQL
 
Session 8 connect your universal application with database .. builders & deve...
Session 8 connect your universal application with database .. builders & deve...Session 8 connect your universal application with database .. builders & deve...
Session 8 connect your universal application with database .. builders & deve...
 
DDL,DML,SQL Functions and Joins
DDL,DML,SQL Functions and JoinsDDL,DML,SQL Functions and Joins
DDL,DML,SQL Functions and Joins
 
Entity Attribute Value (Eav)
Entity   Attribute   Value (Eav)Entity   Attribute   Value (Eav)
Entity Attribute Value (Eav)
 
SQL Overview
SQL OverviewSQL Overview
SQL Overview
 
zekeLabs sql-slides
zekeLabs sql-slideszekeLabs sql-slides
zekeLabs sql-slides
 
45 Essential SQL Interview Questions
45 Essential SQL Interview Questions45 Essential SQL Interview Questions
45 Essential SQL Interview Questions
 

Recently uploaded

Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 

Recently uploaded (20)

MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AI
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 

Table partitioning in PostgreSQL + Rails

  • 1. Table Partitioning PostgreSQL + Rails Agnieszka Figiel, Cambridge Ruby User Group Mar 2014
  • 2. What is table partitioning in PostgreSQL? 1 logical table = n smaller physical tables
  • 3. What are the benefits? improved query performance for big tables * * works best when results are coming from single partition
  • 4. When to consider partitioning? Big table that cannot be queried efficiently, as the index is enormous as well. Rule of thumb: table does not fit into memory
  • 5. How is data split? By ranges: year > 2010 AND year <= 2012 By lists of key values: company_id = 5
  • 6. How does it work? At the heart of it lie 2 mechanisms: ➔ table inheritance ➔ table CHECK constraints
  • 7. Table inheritance: schema CREATE TABLE A (value INT); CREATE TABLE B () INHERITS (A); Table "public.a" Column | Type | Modifiers --------+---------+----------- value | integer | Table "public.b" Column | Type | Modifiers --------+---------+----------- value | integer | Inherits: a
  • 8. Table inheritance: schema CREATE TABLE C (extra_field TEXT) INHERITS (A); Table "public.c" Column | Type | Modifiers -------------+---------+----------- value | integer | extra_field | text | Inherits: a NB: may inherit from multiple tables
  • 9. Table inheritance: querying INSERT INTO A VALUES (0); INSERT INTO B VALUES (10); INSERT INTO C VALUES (20, 'zonk'); SELECT * FROM A WHERE value < 20; value ------- 0 10 SELECT * FROM ONLY A WHERE value < 20; value ------- 0
  • 10. What happened? EXPLAIN ANALYZE SELECT * FROM A WHERE value < 20; QUERY PLAN ---------------------------------------------------------------------------------------------------- Append (cost=0.00..69.38 rows=1290 width=4) (actual time=0.020..0.033 rows=2 loops=1) -> Seq Scan on a (cost=0.00..4.00 rows=80 width=4) (actual time=0.019..0.021 rows=1 loops=1) Filter: (value < 20) -> Seq Scan on b (cost=0.00..40.00 rows=800 width=4) (actual time=0.005..0.006 rows=1 loops=1) Filter: (value < 20) -> Seq Scan on c (cost=0.00..25.38 rows=410 width=4) (actual time=0.005..0.005 rows=0 loops=1) Filter: (value < 20) Rows Removed by Filter: 1
  • 11. Table CHECK constraint CREATE TABLE A (value INT); CREATE TABLE B (CHECK (value < 20)) INHERITS (A); CREATE TABLE C (CHECK (value >= 20)) INHERITS (A); INSERT INTO B VALUES (10); INSERT INTO C VALUES (20); INSERT INTO C VALUES(5); ERROR: new row for relation "c" violates check constraint "c_value_check" DETAIL: Failing row contains (5).
  • 12. Ta da! EXPLAIN ANALYZE SELECT * FROM A WHERE value < 20; QUERY PLAN ---------------------------------------------------------------------------------------------------- Append (cost=0.00..40.00 rows=801 width=4) (actual time=0.015..0.017 rows=1 loops=1) -> Seq Scan on a (cost=0.00..0.00 rows=1 width=4) (actual time=0.002..0.002 rows=0 loops=1) Filter: (value < 20) -> Seq Scan on b (cost=0.00..40.00 rows=800 width=4) (actual time=0.012..0.013 rows=1 loops=1) Filter: (value < 20)
  • 13. Gotcha #1 Make sure that: SET constraint_exclusion = on;
  • 14. Gotcha #2 All check constraints and not-null constraints on a parent table are automatically inherited by its children. Other types of constraints (unique, primary key, and foreign key constraints) are not inherited.
  • 15. Solution #2: create constraints or indexes in all partitions CREATE TABLE A (id serial NOT NULL, value INT NOT NULL); CREATE TABLE B ( CONSTRAINT B_pkey PRIMARY KEY (id), CHECK (value < 20) ) INHERITS (A); CREATE TABLE C ( CONSTRAINT C_pkey PRIMARY KEY (id), CHECK (value >= 20) ) INHERITS (A);
  • 16. Gotcha #3 There is no practical way to enforce uniqueness of a SERIAL id across partitions. INSERT INTO B (value) VALUES (10); INSERT INTO C (value) VALUES (20); INSERT INTO C VALUES (1, 30); SELECT * FROM A; id | value ----+------- 1 | 10 2 | 20 1 | 30
  • 17. Solution #3 ➔ carry on and always filter by partitioning key ➔ use UUID (uuid-ossp)
  • 18. Gotcha #4 Specifying that another table's column REFERENCES a(value) would allow the other table to contain “a values”, but not “b or c values”. There is no good workaround for this case.
  • 19. How to insert / update rows? ➔ PostgreSQL docs recommend using triggers ➔ also possible to do it using rules (overhead, bulk)
  • 20. Trigger example CREATE OR REPLACE FUNCTION a_insert_trigger() RETURNS TRIGGER AS $$ BEGIN IF NEW.value < 20 THEN INSERT INTO b VALUES (NEW.*); ELSE INSERT INTO c VALUES (NEW.*); END IF; RETURN NULL; END; $$ LANGUAGE plpgsql; CREATE TRIGGER insert_a_trigger BEFORE INSERT ON a FOR EACH ROW EXECUTE PROCEDURE a_insert_trigger();
  • 21. Partitioned gem https://github.com/fiksu/partitioned class Company < ActiveRecord::Base; end class ByCompanyId < Partitioned::ByForeignKey self.abstract_class = true belongs_to :company def self.partition_foreign_key return :company_id end partitioned do |partition| partition.index :id, :unique => true end end class Employee < ByCompanyId; end employee = Employee.from_partition(1).find(1)
  • 22. UUID in Rails Rails 4: enable_extension 'uuid-ossp' create_table :documents, id: :uuid do |t| t.string :title t.string :author t.timestamps end Rails 3: gem postgres_ext https://github.com/dockyard/postgres_ext
  • 23. Actual performance improvements? ➔ table with ~13 mln rows ➔ partitioned by date into 8 partitions ➔ complex, long-running query ➔ baseline: 0.07 tps ➔ when results in single partition: 0.15 tps ➔ when results in 2 partitions: like baseline