Postgres 11
I want to make a table calendars
, that is at the same time partitioned by range
(one month of data) and a list
of keys.
The reason is that:
- I want to prune months that are not longer updated.
- I need all the data to be partitioned by list of ids for further joins with and other partitioned table
listings
, that is partitined by the same list of keys.
The documentation says:
Declarative partitioning only supports range, list and hash partitioning, whereas table inheritance allows data to be divided in a manner of the user's choosing.
Thus, if I get it right, this means that my taks can not be done with Declarative partitioning, but probably can be done using Inheritance.
So, I try to reproduce the given example with my modification
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
) PARTITION BY RANGE (logdate); # this already does not accept mixed types of partitioning
than I try to create a partition with my mixed rules of partitining:
CREATE TABLE measurement_y2006m02 (
CHECK ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01'
AND paektamp >0 AND peaktemp <=10)
) INHERITS (measurement);
this gives:
cannot inherit from partitioned table "measurement"
Thank you!
-
1You shouldn't be using inheritance based partitioning anymore. Use declarative partitioninguser1822– user18222020年10月22日 08:58:36 +00:00Commented Oct 22, 2020 at 8:58
-
1I think you are looking for sub-partitioning. First use range partitioning on date, then create sub-partitions by list of IDsuser1822– user18222020年10月22日 08:59:42 +00:00Commented Oct 22, 2020 at 8:59
-
@a_horse_with_no_name, you mean it's possible to partition by range, followed by sub-partition by list?Dmitriy Grankin– Dmitriy Grankin2020年10月22日 09:07:53 +00:00Commented Oct 22, 2020 at 9:07
-
1Yes, but if you want this to be efficient, you really should be using declarative partitioning (I am not sure if that would even be possible with the deprecated inheritance based partitioning)user1822– user18222020年10月22日 09:12:58 +00:00Commented Oct 22, 2020 at 9:12
-
1"To implement sub-partitioning, specify the PARTITION BY clause in the commands used to create individual partitions, for example:"user1822– user18222020年10月22日 09:20:54 +00:00Commented Oct 22, 2020 at 9:20
1 Answer 1
A partition can again be a partitioned table, so using subpartitions you can partition a table in two different ways:
CREATE TABLE calendar (
id bigint NOT NULL,
day date NOT NULL
) PARTITION BY RANGE (day);
CREATE TABLE calendar_2020 PARTITION OF calendar
FOR VALUES FROM ('2020-01-01') TO ('2021-01-01') PARTITION BY LIST (id);
CREATE TABLE calendar_2020_a
PARTITION OF calendar_2020 FOR VALUES IN (1, 2, 42);
Make sure to test carefully if you get the desired performance benefits; you probably have to turn on enable_partitionwise_join
.
Also make sure that you use a recent PostgreSQL version (≥ x12) and that you don't end up with thousands of partitions.
-
1. I will be having thousands of partitions in my case, what is possibly bad about it? 2. I am using postgres 11, do I really have to move to 12? If so, how to do it in an easy way?Dmitriy Grankin– Dmitriy Grankin2020年10月22日 10:46:00 +00:00Commented Oct 22, 2020 at 10:46
-
Thousands of partitions is pushing the limits. Query planning time will increase, for one. You will need to raise a number of parameters, like
autovacuum_max_workers
,max_files_per_process
andmax_locks_per_transaction
. You will have to test if the performance is still acceptable. v12 has improvements in that area. Upgrade can be as simple as runningpg_upgrade
.Laurenz Albe– Laurenz Albe2020年10月22日 10:49:05 +00:00Commented Oct 22, 2020 at 10:49 -
Does the order make any difference? e.g. having it first partitioned by LIST (id) and the by RANGE (day) ? @LaurenzAlbeYannick Schuchmann– Yannick Schuchmann2022年03月30日 12:34:00 +00:00Commented Mar 30, 2022 at 12:34
-
1@YannickSchuchmann That depends on your query. Partition pruning will be different.Laurenz Albe– Laurenz Albe2022年03月30日 13:01:58 +00:00Commented Mar 30, 2022 at 13:01