基本上,您在下面描述了两种情况。
- 表很大,需要把数据拆分成几个分区
- 该表获得第一个分区,您为新数据添加新分区
让我们将此设置用于未分区桌子
create table jdbn.non_part
(id int not null, name varchar(100));
insert into jdbn.non_part (id,name)
SELECT id, 'xxxxx'|| id::varchar(20) name
from generate_series(1,1000) id;
该表包含从 1 到 1000 的 id,对于第一种情况,您需要将它们分成两个分区,每个分区 500 行。
创建分区表
具有与原始表相同的结构和约束
create table jdbn.part
(like jdbn.non_part INCLUDING DEFAULTS INCLUDING CONSTRAINTS)
PARTITION BY RANGE (id);
添加分区
覆盖当前数据
create table jdbn.part_500 partition of jdbn.part
for values from (1) to (501); /* 1 <= id < 501 */
create table jdbn.part_1000 partition of jdbn.part
for values from (501) to (1001);
用于未来数据(根据需要)
create table jdbn.part_1500 partition of jdbn.part
for values from (1001) to (1501);
使用insert复制数据
请注意,这种方法复制数据意味着您需要两倍的空间并可能清理旧数据。
insert into jdbn.part (id,name)
select id, name from jdbn.non_part;
检查分区修剪
注意只访问part_500分区
EXPLAIN SELECT * FROM jdbn.part WHERE id <= 500;
QUERY PLAN |
----------------------------------------------------------------+
Seq Scan on part_500 part (cost=0.00..14.00 rows=107 width=222)|
Filter: (id <= 500) |
第二个选项 - 将数据移动到一个分区
如果您可以接受一个(大)初始分区,则可以使用第二种方法
创建分区表
同上
附加表作为分区
ALTER TABLE jdbn.part ATTACH PARTITION jdbn.non_part
for values from (1) to (1001);
现在原始表获得分区表的第一个分区。 IE。不执行数据复制。
EXPLAIN SELECT * FROM jdbn.part WHERE id <= 500;
QUERY PLAN |
---------------------------------------------------------------+
Seq Scan on non_part part (cost=0.00..18.50 rows=500 width=12)|
Filter: (id <= 500) |
类似的答案和一些分区创建自动化的提示here