我有一个表,每天累积数百万行。最新数据的查询频率最高,而随着数据的老化,查询频率也会降低。
为了提高性能,我已经按月对数据进行了分区,创建的表是这样的……
CREATE TABLE banana ( recTime TIMESTAMP, blah blah blah) PARTION BY RANGE (recTime);
CREATE TABLE banana_201704 PARTITION OF banana FOR VALUES FROM ('2017-04-01' ) TO ( '2017-05-01' ) ;
CREATE TABLE banana_201705 PARTITION OF banana FOR VALUES FROM ('2017-05-01' ) TO ( '2017-06-01' ) ;
我注意到在月初我从该表中获得了很好的性能,大概是因为在该月的那个时候它的记录很少,随着月的进行(表变得更大),性能下来。
基于这个原因,我认为如果按天而不是按月进行分区,则性能会更好。但是,我不想按天对整个表进行分区,最终会产生很多小的分区要管理。
是否可以以某种方式无缝地将分区合并在一起,以便(假设)30天后,所有单独的“ day”分区都可以合并到一个大的“ month”分区中,而无需从一个表中简单选择性能开销,插入另一个,然后删除原始记录?
还是有更好的方法来管理此问题?
答案 0 :(得分:0)
一个月后,您应该从基本表中选择创建一个月度表,删除每日分区,并将月度表附加为分区。
创建2018年1月的每日分区:
do $$
declare d date;
begin
for d in
select generate_series('2018-01-01'::date, '2018-01-31', '1d')::date
loop
execute format($ex$
create table banana_%s partition of banana for values from (%L) to (%L)
$ex$, replace(d::text, '-', ''), d, d+ 1);
end loop;
end;
$$;
为月份创建一个分区,然后删除每日分区:
create table banana_201801 as
select * from banana
where created_at between '2018-01-01' and '2018-01-31';
do $$
declare d date;
begin
for d in
select generate_series('2018-01-01'::date, '2018-01-31', '1d')::date
loop
execute format($ex$
drop table banana_%s
$ex$, replace(d::text, '-', ''));
end loop;
end;
$$;
alter table banana
attach partition banana_201801 for values from ('2018-01-01') to ('2018-02-01');