0

我有一个大约 270,000,000 行的表,这就是我创建它的方式。

CREATE TABLE init_package_details AS
    SELECT pcont.package_content_id as package_content_id,
                    pcont.activity_id as activity_id,
                    pc.org_id as org_id,
                    pc.bed_type as bed_type,
                    pc.is_override as is_override,
                    pmmap.package_id as package_id,
                    pcont.activity_qty as activity_qty,
                    pcont.charge_head as  charge_head,
                    pcont.activity_charge as charge,
                    COALESCE(pc.charge,0) - COALESCE(pc.discount,0) as package_charge 
    FROM a pc
                    JOIN b od ON
                                (od.org_id = pc.org_id AND od.status='A')
                    JOIN c pm ON 
                                (pc.package_id=pm.package_id)
                    JOIN d pmmap ON
                                (pmmap.pack_master_id=pm.package_id)
                    JOIN e pcont ON 
                                (pcont.package_id=pmmap.package_id);

我需要在init_package_details表上建立索引。

该表在 5-6 分钟左右创建。

我已经创建了 btree 索引,例如,

CREATE INDEX init_package_details_package_content_id_idx 
   ON init_package_details(package_content_id);`

这需要 10 分钟(超过创建和填充表格本身的时间

而且,当我创建另一个索引时,

CREATE INDEX init_package_details_package_act_org_bt_id_idx 
   ON init_package_details(activity_id,org_id,bed_type);

它只是冻结并永远完成。我等了大约 30 分钟才手动取消它。

以下是iotop -o如果有帮助的统计数据,

  • 当我创建平均大约 110-120 MB/s 的表时(这就是在 5-6 分钟内插入 2.7 亿行的方式)
  • 当我创建第一个索引时,它的平均速度约为 70 MB/s
  • 在第二个索引上,它以 5-7 MB/s 的速度缓慢增长

有人可以解释为什么会这样吗?无论如何我可以在这里加快索引创建速度吗?

编辑 1:没有其他连接访问该表。并且,在整个运行时间内pg_stat_activity显示为状态。active这发生在事务内部(发生在BEGIN和之间COMMIT,它在同一文件中包含许多其他脚本.sql)。

编辑2:

 postgres=# show work_mem ;
 work_mem
----------
 5MB
(1 row)

postgres=# show maintenance_work_mem;
 maintenance_work_mem
----------------------
 16MB
4

1 回答 1

3

建立索引需要很长时间,这很正常。

如果您在 I/O 上没有遇到瓶颈,那么您可能在 CPU 上。

有几件事可以提高性能:

  • 设置maintenance_work_mem很高。

  • 使用 PostgreSQL v11 或更高版本,可以使用多个并行工作程序。

于 2019-07-12T06:09:21.200 回答