正如其他人所说,分区是您的答案,但是:
我会分区一些hash(a)
. 如果a
是一个整数,那么a%256
会很好。如果是文本,则类似于substring(md5(a) for 2)
.
它将加速插入和选择。
对于删除,我会让它们更频繁地运行,但更小并且也被分区。我会每小时运行一次(在 XX:30),就像这样:
delete from table_name
where date<(current_date - interval '1 year')
and
hash(a)
=
(extract(doy from current_timestamp) * 24
+ extract(hour from current_timestamp))::int % 256;
编辑:我刚刚测试过这个:
create function hash(a text) returns text as $$ select substring(md5($1) for 1) $$ language sql immutable strict;
CREATE TABLE tablename (id text, mdate date);
CREATE TABLE tablename_partition_0 ( CHECK ( hash(id) = '0' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_1 ( CHECK ( hash(id) = '1' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_2 ( CHECK ( hash(id) = '2' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_3 ( CHECK ( hash(id) = '3' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_4 ( CHECK ( hash(id) = '4' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_5 ( CHECK ( hash(id) = '5' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_6 ( CHECK ( hash(id) = '6' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_7 ( CHECK ( hash(id) = '7' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_8 ( CHECK ( hash(id) = '8' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_9 ( CHECK ( hash(id) = '9' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_a ( CHECK ( hash(id) = 'a' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_b ( CHECK ( hash(id) = 'b' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_c ( CHECK ( hash(id) = 'c' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_d ( CHECK ( hash(id) = 'd' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_e ( CHECK ( hash(id) = 'e' ) ) INHERITS (tablename);
CREATE TABLE tablename_partition_f ( CHECK ( hash(id) = 'f' ) ) INHERITS (tablename);
analyze;
explain select * from tablename where id='bar' and hash(id)=hash('bar');
查询计划
-------------------------------------------------- ------------------------------------------
结果(成本=0.00..69.20 行=2 宽度=36)
-> 追加(成本=0.00..69.20 行=2 宽度=36)
-> 对表名进行 Seq 扫描(成本=0.00..34.60 行=1 宽度=36)
过滤器: ((id = 'bar'::text) AND ("substring"(md5(id), 1, 1) = '3'::text))
-> 对 tablename_partition_3 表名进行 Seq 扫描(成本=0.00..34.60 行=1 宽度=36)
过滤器: ((id = 'bar'::text) AND ("substring"(md5(id), 1, 1) = '3'::text))
(6 行)
您需要添加hash(id)=hash('searched_value')
到查询中,否则 Postgres 将搜索所有表。
编辑:您还可以使用规则系统自动插入更正表:
create rule tablename_rule_0 as
on insert to tablename where hash(NEW.id)='0'
do instead insert into tablename_partition_0 values (NEW.*);
create rule tablename_rule_1 as
on insert to tablename where hash(NEW.id)='1'
do instead insert into tablename_partition_1 values (NEW.*);
-- and so on
insert into tablename (id) values ('a');
select * from tablename_partition_0;
id | mdate
----+-------
a |
(1 row)