All Products
Search
Document Center

AnalyticDB for PostgreSQL:Define table partitioning

Last Updated:Jan 25, 2024

AnalyticDB for PostgreSQL allows you to divide a large table into partitions. When you use conditions to query data, the system scans only the partitions that meet the specified conditions. This prevents full table scans and improves query performance.

Supported partitioning types

  • Range partitioning: Data is divided based on a numeric range, such as date.

  • List partitioning: Data is divided based on a list of values, such as city attributes.

  • Multi-level partitioning: Data is divided based on a numeric range and a list of values.

Create a range partitioned table

You can have AnalyticDB for PostgreSQL automatically generate partitions by specifying a START value, an END value, and an EVERY clause that defines the interval within the range. By default, the START value is inclusive and the END value is exclusive.

Create a table that is range-partitioned by date. Sample statement:

CREATE TABLE sales (id int, date date, amt decimal(10,2))
DISTRIBUTED BY (id)
PARTITION BY RANGE (date)
( START (date '2016-01-01') INCLUSIVE
   END (date '2017-01-01') EXCLUSIVE
   EVERY (INTERVAL '1 day') );

Create a table that is range-partitioned by number. For example, a column of the INT data type can be used as the partition key. Sample statement:

CREATE TABLE rank (id int, rank int, year int, gender char(1), count int)
DISTRIBUTED BY (id)
PARTITION BY RANGE (year)
( START (2006) END (2016) EVERY (1), 
  DEFAULT PARTITION extra ); 

Create a list partitioned table

When you create a list partitioned table, you can set the partition key to any column whose data type allows value comparison, and you must declare a description for each specified value of the partition key.

Create a list partitioned table. Sample statement:

CREATE TABLE rank (id int, rank int, year int, gender 
char(1), count int ) 
DISTRIBUTED BY (id)
PARTITION BY LIST (gender)
( PARTITION girls VALUES ('F'), 
  PARTITION boys VALUES ('M'), 
  DEFAULT PARTITION other );

Create a multi-level partitioned table

AnalyticDB for PostgreSQL allows you to create a table that has multi-level partitions. The following example demonstrates how to create a three-level partitioned table. Data in level-1 partitions is range-partitioned by year, data in level-2 partitions is range-partitioned by month, and data in level-3 partitions is list-partitioned by region. The level-2 and level-3 partitions are called subpartitions.

CREATE TABLE sales (id int, year int, month int, day int,
region text)
DISTRIBUTED BY (id)
PARTITION BY RANGE (year)
    SUBPARTITION BY RANGE (month)
       SUBPARTITION TEMPLATE (
        START (1) END (13) EVERY (1),
        DEFAULT SUBPARTITION other_months )
           SUBPARTITION BY LIST (region)
             SUBPARTITION TEMPLATE (
               SUBPARTITION usa VALUES ('usa'),
               SUBPARTITION europe VALUES ('europe'),
               SUBPARTITION asia VALUES ('asia'),
               DEFAULT SUBPARTITION other_regions )
( START (2002) END (2012) EVERY (1),
  DEFAULT PARTITION outlying_years );

Add a partition

You can execute an ALTER TABLE statement to add a partition to a partitioned table. If a subpartition template is used when the partitioned table is created, the added partition is also subpartitioned accordingly. The following example demonstrates how to add a partition:

ALTER TABLE sales ADD PARTITION 
            START (date '2017-02-01') INCLUSIVE 
            END (date '2017-03-01') EXCLUSIVE;

If no subpartition template is used when the partitioned table is created, you can define subpartitions when you add a partition. The following example demonstrates how to add a partition and define its subpartitions:

ALTER TABLE sales ADD PARTITION 
            START (date '2017-02-01') INCLUSIVE 
            END (date '2017-03-01') EXCLUSIVE
      ( SUBPARTITION usa VALUES ('usa'), 
        SUBPARTITION asia VALUES ('asia'), 
        SUBPARTITION europe VALUES ('europe') );

You can also use an ALTER TABLE statement to subpartition an existing partition. Sample statement:

ALTER TABLE sales ALTER PARTITION FOR (RANK(12))
      ADD PARTITION africa VALUES ('africa');
Note

Partitions cannot be added to a partitioned table that has a default partition. To add partitions to such a partitioned table, you can split the default partition. For more information, see the "Split a partition" section of this topic.

Specify a name for a child partitioned table

When you create a partitioned table, you can specify names for child partitioned tables as of AnalyticDB for PostgreSQL V6.3.10.9 by using the WITH(tablename=<tablename_1>) clause.

Sample statements:

CREATE TABLE partition_with_name_list (a int, b int, c int) DISTRIBUTED BY (a) PARTITION BY LIST (a)
(
    PARTITION p1 VALUES (1)  WITH (tablename='partition_with_name_list_p1'),
    PARTITION p2 VALUES (2)  WITH (tablename='partition_with_name_list_p2'),
    PARTITION p3 VALUES (3)  WITH (tablename='partition_with_name_list_p3'),
    PARTITION p4 VALUES (4)  WITH (tablename='partition_with_name_list_p4')
);

Split a partition

You can execute an ALTER TABLE statement to split a partition into two partitions. Partition splitting is subject to the following limits:

  • If subpartitions exist, only the lowest level of subpartitions can be split.

  • The split value specified in the AT clause of the partition splitting statement is assigned to the second partition.

For example, assume that a partition that contains the data of January 2017 is split into two partitions. The first partition contains the data of January 1 to January 15 and the second partition contains the data of January 16 to January 31. Sample statement:

ALTER TABLE sales SPLIT PARTITION FOR ('2017-01-01')
AT ('2017-01-16')
INTO (PARTITION jan171to15, PARTITION jan1716to31);

If your partitioned table has a default partition, you can add a partition by splitting the default partition. In the INTO clause, you must specify the default partition as the second partition. Sample statement:

ALTER TABLE sales SPLIT DEFAULT PARTITION 
START ('2017-01-01') INCLUSIVE 
END ('2017-02-01') EXCLUSIVE 
INTO (PARTITION jan17, default partition);

Determine the partition granularity

When you use partitioned tables, you may need to determine the partition granularity. For example, to partition a table by time, you can choose a granularity of day, week, or month. A finer granularity results in less data in each partition but a larger number of partitions. The number of partitions is not measured by an absolute standard. We recommend that you assign no more than 200 partitions in each table. A large number of partitions may reduce database performance. For example, the query optimizer takes a long time to generate execution plans or the VACUUM operation takes a long time to complete.

Optimize partitioned table queries

AnalyticDB for PostgreSQL supports partition pruning for partitioned tables to improve query performance. When partition pruning is enabled, the system scans only the required partitions based on query conditions, instead of scanning the entire table. Example:

EXPLAIN 
  SELECT * FROM sales 
  WHERE year = 2008 
    AND month = 1 
    AND day = 3 
    AND region = 'usa';

In the preceding example, the query conditions fall on the level-3 partition usa in the level-2 partition 1 in the level-1 partition 2008. Therefore, only the data in the level-3 partition usa is scanned during the query. The following execution plan shows that only one of the 468 level-3 partitions needs to be scanned.

Gather Motion 4:1  (slice1; segments: 4)  (cost=0.00..431.00 rows=1 width=24)
  ->  Sequence  (cost=0.00..431.00 rows=1 width=24)
        ->  Partition Selector for sales (dynamic scan id: 1)  (cost=10.00..100.00 rows=25 width=4)
              Filter: year = 2008 AND month = 1 AND region = 'usa'::text
              Partitions selected:  1 (out of 468)
        ->  Dynamic Table Scan on sales (dynamic scan id: 1)  (cost=0.00..431.00 rows=1 width=24)
              Filter: year = 2008 AND month = 1 AND day = 3 AND region = 'usa'::text

Query partition definitions

You can execute the following SQL statement to query the definitions of all partitions in a table:

SELECT 
  partitionboundary, 
  partitiontablename, 
  partitionname,
  partitionlevel, 
  partitionrank
FROM pg_partitions 
WHERE tablename='sales';

Maintain partitioned tables

You can manage partitions in partitioned tables. For example, you can add, remove, rename, truncate, exchange, and split partitions. For more information, see Partitioning Large Tables.

Rename a child partitioned table

You can rename child partitioned tables as of AnalyticDB for PostgreSQL V6.3.10.9.

Sample statement for changing the name of a child partitioned table from partition_with_name_list_p1 to partition_with_name_list_p1r:

ALTER TABLE partition_with_name_list_p1 RENAME TO partition_with_name_list_p1r;

FAQ

Q: How can I specify a partition key for a table?

A: If your table has a primary key, you must specify a primary key column as the partition key. If your table does not have a primary key, your can specify any column as the partition key.