Table partition in PostgreSQL

Table partitioning is the practice of splitting a large table into smaller sub-tables and each sub-table is created using separate CREATE TABLE commands. So every time you query data, PostgreSQL scan and process a smaller subset of data instead of doing in on the large table. Therefore, query performance would be improved tremendously.

PostgreSQL supports three types of built-in partitioning types:

  • Range Partitioning: The data rows are distributed to partitions based on column values falling within a given range.
  • List Partitioning: The table is partitioned by explicitly listing which key values appear in each partition.
  • Hash Partitioning: Rows are evenly distributed across all partitions using a hash value of a partitioning key.

In the below example , we will show how a list partition works

Create a new table called transaction in a separate tablespace

 CREATE TABLE IF NOT EXISTS netbnk_schm.transaction
  (
      transaction_id integer NOT NULL,
      transaction_date date,
      card_type varchar(100),
      banks varchar(100)
  ) partition by list(card_type);  TABLESPACE new_tbs 
CREATE TABLE
netbank=# \d transaction
              Partitioned table "netbnk_schm.transaction"
       Column      |          Type          | Collation | Nullable | Default
 ------------------+------------------------+-----------+----------+---------
  transaction_id   | integer                |           | not null |
  transaction_date | date                   |           |          |
  card_type        | character varying(100) |           |          |
  banks            | character varying(100) |           |          |
 Partition key: LIST (card_type)
 Number of partitions: 2 (Use \d+ to list them.)

Table is created successfully , now create two new tablespace and corresponding two new where we need to store the data based on the list partition .

[root@parweztestinstance ~]# mkdir -p /var/oled/test_tbs2
[root@parweztestinstance ~]# chown -R postgres:postgres /var/oled/test_tbs2
[postgres@parweztestinstance ~]$ psql
 psql (14.4)
 Type "help" for help.
 postgres=# \c netbank
 You are now connected to database "netbank" as user "postgres".

netbank=# CREATE TABLESPACE new_tbs_2 owner olap LOCATION '/var/oled/test_tbs2' ;
 CREATE TABLESPACE

List the new tablespace created 
netbank=# \db
              List of tablespaces
     Name    |  Owner   |      Location
 ------------+----------+---------------------
  new_tbs_2  | olap     | /var/oled/test_tbs2
  new_tbs_3  | olap     | /var/oled/test_tbs3

Create two new partition table

netbank=# create table netbnk_schm.transaction_part2 partition of netbnk_schm.transaction_part for values IN('mastercard') TABLESPACE new_tbs_3;
CREATE TABLE


netbank=# create table netbnk_schm.transaction_part partition of netbnk_schm.transaction_part for values IN('VISA') TABLESPACE new_tbs_2; 
CREATE TABLE

Check all tables

netbank=# set search_path=netbnk_schm;
 SET
 netbank=#
 netbank=#
 netbank=#
 netbank=# \dt
                        List of relations
    Schema    |       Name        |       Type        |  Owner
 -------------+-------------------+-------------------+----------
  netbnk_schm | transaction       | partitioned  table | olap
  netbnk_schm | transaction_part  | table              | olap 
  netbnk_schm | transaction_part2 | table              | olap 
 (3 rows)

Now insert some data based on list of partition key it will send to the corresponding partition table

netbank=# insert into netbnk_schm.transaction values(12,'1/12/2001','mastercard',  'sbi');
 insert into  netbnk_schm.transaction   values(13,'1/13/2001',        'mastercard',  'al rajhi');
 insert into  netbnk_schm.transaction   values(14,'1/14/2001',        'mastercard',  'bny');
 insert into  netbnk_schm.transaction   values(15,'1/15/2001',        'mastercard',      'jp morgan');
 insert into  netbnk_schm.transaction   values(16,'1/16/2001',        'mastercard',      'al jazeera');
 
 INSERT 0 1

select and check

netbank=# select * from  netbnk_schm.transaction_part2  ;
  transaction_id | transaction_date | card_type  |   banks
 ----------------+------------------+------------+------------
              12 | 2001-01-12       | mastercard | sbi
              13 | 2001-01-13       | mastercard | al rajhi
              14 | 2001-01-14       | mastercard | bny
              15 | 2001-01-15       | mastercard | jp morgan
              16 | 2001-01-16       | mastercard | al jazeera
              17 | 2001-01-17       | mastercard | sabb
              19 | 2001-01-18       | mastercard | hsbc
              18 | 2001-01-19       | mastercard | hsbc
              20 | 2001-01-20       | mastercard | sbi
 (9 rows)

similarly insert for another value in key

insert into netbnk_schm.transaction values(2,'1/2/2001',    'VISA',        'hsbc');
 insert into netbnk_schm.transaction values(3,'1/3/2001',    'VISA',        'hsbc');
 insert into netbnk_schm.transaction values(4,'1/4/2001',    'VISA',        'sbi');
 insert into netbnk_schm.transaction values(5,'1/5/2001',    'VISA',        'al rajhi');
 insert into netbnk_schm.transaction values(6,'1/6/2001',    'VISA',        'bny');
 insert into netbnk_schm.transaction values(7,'1/7/2001',    'VISA',        'jp morgan');
INSERT 0 1
netbank=# select * from transaction_part;
  transaction_id | transaction_date | card_type |   banks
 ----------------+------------------+-----------+------------
              11 | 2001-01-11       | VISA      | hsbc
               2 | 2001-01-02       | VISA      | hsbc
               2 | 2001-01-02       | VISA      | hsbc
               3 | 2001-01-03       | VISA      | hsbc
               4 | 2001-01-04       | VISA      | sbi
               5 | 2001-01-05       | VISA      | al rajhi
               6 | 2001-01-06       | VISA      | bny
               7 | 2001-01-07       | VISA      | jp morgan
               8 | 2001-01-08       | VISA      | al jazeera
               9 | 2001-01-09       | VISA      | sab

Check the tables and tablespace details

netbank=# \dt
                             List of relations
    Schema    |            Name            |       Type        |  Owner
 -------------+----------------------------+-------------------+----------
 netbnk_schm | transaction_par2           |   table             | olap
 netbnk_schm | transaction_part           |   table            | olap
 netbnk_schm | transaction                |   partitioned table | olap
netbank=# select tablename,tablespace from pg_tables where schemaname='netbnk_schm' ;
          tablename          | tablespace
 ----------------------------+------------
  transaction                |new_tbs
  transaction_part           |new_tbs_2
  transaction_part2          |new_tbs_3
netbank=# \d+ transaction
                                         Partitioned table "netbnk_schm.transaction"
       Column      |          Type          | Collation | Nullable | Default | Storage  | Compression | Stats target | Description
 ------------------+------------------------+-----------+----------+---------+----------+-------------+--------------+-------------
  transaction_id   | integer                |           | not null |         | plain    |             |              |
  transaction_date | date                   |           |          |         | plain    |             |              |
  card_type        | character varying(100) |           |          |         | extended |             |              |
  banks            | character varying(100) |           |          |         | extended |             |              |
 Partition key: LIST (card_type)
 Partitions: transaction_part FOR VALUES IN ('VISA'),
             transaction_part2 FOR VALUES IN ('mastercard')

Range partioning examples

 netbank=# CREATE TABLE measurement (
    city_id         int not null,
    logdate         date not null,
    peaktemp        int,
    unitsales       int
    PARTITION BY RANGE (logdate);
 CREATE TABLE


netbank=# CREATE TABLE measurement_y2006m02 PARTITION OF measurement FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');
 CREATE TABLE

netbank=# CREATE TABLE measurement_y2006m03 PARTITION OF measurement FOR  VALUES FROM ('2006-03-01') TO ('2006-04-01');
 CREATE TABLE


netbank=# CREATE TABLE measurement_y2007m11 PARTITION OF measurement FOR VALUES FROM ('2007-11-01') TO ('2007-12-01');
 CREATE TABLE

netbank=# CREATE TABLE measurement_y2007m12 PARTITION OF measurement FOR VALUES FROM ('2007-12-01') TO ('2008-01-01')
TABLESPACE olap_tbs;
 CREATE TABLE

Create an index on  PARTITION  column it  will create index on all  PARTITION  table 


netbank=# CREATE INDEX ON measurement (logdate);
 CREATE INDEX


netbank=# \d+ measurement
                                 Partitioned table "netbnk_schm.measurement"
   Column   |  Type   | Collation | Nullable | Default | Storage | Compression | Stats target | Description
 -----------+---------+-----------+----------+---------+---------+-------------+--------------+-------------
  city_id   | integer |           | not null |         | plain   |             |              |
  logdate   | date    |           | not null |         | plain   |             |              |
  peaktemp  | integer |           |          |         | plain   |             |              |
  unitsales | integer |           |          |         | plain   |             |              |
 Partition key: RANGE (logdate)
 Indexes:
     "measurement_logdate_idx" btree (logdate)
 Partitions: measurement_y2006m02 FOR VALUES FROM ('2006-02-01') TO ('2006-03-01'),
             measurement_y2006m03 FOR VALUES FROM ('2006-03-01') TO ('2006-04-01'),
             measurement_y2007m11 FOR VALUES FROM ('2007-11-01') TO ('2007-12-01'),
             measurement_y2007m12 FOR VALUES FROM ('2007-12-01') TO ('2008-01-01')


Insert some values according to dates, it will send the entries for respective dates into their own par Partition tables .

netbank=# insert into netbnk_schm.measurement values(1,'2006-02-18',33,5) ;
 INSERT 0 1
netbank=# insert into netbnk_schm.measurement values(1,'2006-02-28',33,5) ;
 INSERT 0 1
netbank=# insert into netbnk_schm.measurement values(1,'2006-02-11',33,5) ;
 INSERT 0 1
netbank=# insert into netbnk_schm.measurement values(1,'2007-11-01',33,5) ;
 INSERT 0 1
netbank=# insert into netbnk_schm.measurement values(1,'2007-11-22',33,5) ;
 INSERT 0 1
netbank=# insert into netbnk_schm.measurement values(12,'2007-12-3',32,4) ;
 INSERT 0 1

Check the data now



netbank=# select * from measurement ;
  city_id |  logdate   | peaktemp | unitsales
 ---------+------------+----------+-----------
        1 | 2006-02-18 |       33 |         5
        1 | 2006-02-28 |       33 |         5
        1 | 2006-02-11 |       33 |         5
        1 | 2007-11-01 |       33 |         5
        1 | 2007-11-22 |       33 |         5
       12 | 2007-12-03 |       32 |         4
 (6 rows)

netbank=# select * from measurement_y2006m02 ;
  city_id |  logdate   | peaktemp | unitsales
 ---------+------------+----------+-----------
        1 | 2006-02-18 |       33 |         5
        1 | 2006-02-28 |       33 |         5
        1 | 2006-02-11 |       33 |         5
 (3 rows)

netbank=# select * from measurement_y2007m12 ;
  city_id |  logdate   | peaktemp | unitsales
 ---------+------------+----------+-----------
       12 | 2007-12-03 |       32 |         4
 (1 row)


netbank=# select * from measurement_y2007m11 ;
  city_id |  logdate   | peaktemp | unitsales
 ---------+------------+----------+-----------
        1 | 2007-11-01 |       33 |         5
        1 | 2007-11-22 |       33 |         5
 (2 rows)

 485 total views,  1 views today

Leave a Reply

Your email address will not be published. Required fields are marked *