Postgres 在插入时的性能差异

6 postgresql performance query-performance

我试图对一张大表进行分区,并且出现了我无法解释的这种 Postgres 行为。也许你会有什么建议?

我走得很直接(我知道这不是最有效的,但我仍然有一些时间):

create table target_table  as select * from parent_table limit 0;
insert into target_table select * from parent_table where date_field >= '20120101' and date_field <='20120131' and tariff_id <> -1;
insert into target_table select * from parent_table where date_field >= '20120201' and date_field <='20120228' and tariff_id <> -1;
insert into target_table select * from parent_table where date_field >= '20120301' and date_field <='20120331' and tariff_id <> -1;
insert into target_table select * from parent_table where date_field >= '20120401' and date_field <='20120430' and tariff_id <> -1;
insert into target_table select * from parent_table where date_field >= '20120501' and date_field <='20120531' and tariff_id <> -1;
.....
Run Code Online (Sandbox Code Playgroud)

并且有结果每个命令花费了多少时间来执行:

08:44:42  [INSERT - 8981055 row(s), 119.962 secs]  Command processed
08:46:36  [INSERT - 8222656 row(s), 114.057 secs]  Command processed
08:48:43  [INSERT - 8981454 row(s), 126.789 secs]  Command processed
08:51:02  [INSERT - 8929325 row(s), 139.815 secs]  Command processed
08:53:13  [INSERT - 9465383 row(s), 130.752 secs]  Command processed
08:55:25  [INSERT - 9302664 row(s), 131.911 secs]  Command processed
08:57:36  [INSERT - 9581798 row(s), 130.853 secs]  Command processed
08:59:58  [INSERT - 10080875 row(s), 142.071 secs]  Command processed
09:15:03  [INSERT - 9717698 row(s), 905.030 secs]  Command processed
10:24:22  [INSERT - 10169181 row(s), 4159.346 secs]  Command processed
11:33:11  [INSERT - 10000601 row(s), 4128.590 secs]  Command processed
12:38:36  [INSERT - 10576846 row(s), 3924.579 secs]  Command processed
Run Code Online (Sandbox Code Playgroud)

我找不到解释为什么有时从同一张表插入需要 2 分钟,有时需要 1 小时!这种行为的原因是什么?

一些信息:

运行在亚马逊云 xlarge EC2 实例上的 PG 服务器。
我是唯一的一个用户,它没有被其他任务超载。
work_mem = '1GB'
parent_table相当大 - 8 亿行。

SCO*_*SCO 0

我想说你的目标表可能是:

  • 有一个索引。维护索引并不便宜,因此索引的项目越多,添加更多项目的成本就越高。一个技巧是删除索引,并在插入完成后重新索引表。当然如果可以的话。

  • 没有可以减轻索引更新成本的分区(除了索引之外)。

尝试删除 target_table 上的索引,然后重试导入。