Postgres多列索引需要永远完成

时间:2019-07-12 04:35:05

标签: postgresql indexing query-performance b-tree-index

我有一个约有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显示为状态。这发生在事务内部(发生在BEGINCOMMIT之间,它在同一.sql文件中包含许多其他脚本)。

编辑2:

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

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

1 个答案:

答案 0 :(得分:3)

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

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

有几件事可以改善性能:

  • maintenance_work_mem设置得很高。

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