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 亿行。
我想说你的目标表可能是:
有一个索引。维护索引并不便宜,因此索引的项目越多,添加更多项目的成本就越高。一个技巧是删除索引,并在插入完成后重新索引表。当然如果可以的话。
没有可以减轻索引更新成本的分区(除了索引之外)。
尝试删除 target_table 上的索引,然后重试导入。