我正在尝试将一个表合并到一个分区中,合并有效但性能不佳。我读过这个链接,特别是这个引用....
在运行 ATTACH PARTITION 命令之前,建议在要附加的表上创建一个 CHECK 约束,描述所需的分区约束。这样,系统将能够跳过扫描以验证隐式分区约束。如果没有这样的约束,将扫描表以验证分区约束,同时在父表上持有 ACCESS EXCLUSIVE 锁。然后可以在 ATTACH PARTITION 完成后删除约束,因为它不再是必需的。
这是我正在使用的 SQL……
ALTER TABLE mess_201811 ADD CONSTRAINT const_201811 CHECK ( loadedtime >= DATE '2018-11-01' AND loadedtime < DATE '2018-11-23' );
ALTER TABLE mess ATTACH PARTITION mess_201811 FOR VALUES FROM ('2018-11-01') TO ('2018-11-23');
ALTER TABLE mess_201811 DROP CONSTRAINT const_201811 ;
我尽可能地从提到的链接中复制了我的 SQL。这三个命令都没有问题,问题是它花费的时间。添加约束大约需要 60 秒(很公平,表中大约有 200 万条记录)。然而,ATTACH PARTITION 命令也需要大约 60 秒,这向我表明正在对表进行第二次扫描以验证分区。我的理解是,有了 CHECK 约束,ATTACH 应该是一个简单的 DDL 语句,并且只需要几分之一秒。
问题是 ATTACH PARTITION 需要对 table mess的排他锁,这会阻止插入记录 60 秒。
我正在使用 postgres v10.5。table mess 的定义以
PARTITIONED BY loadedtime;
在我测试时,数据库上没有其他用户,也没有锁定问题。
在 jjanes 解决方案之后,我检查了原始文档,引用的示例确实使用了 NOT NULL 字段约束,尽管它没有提到这是强制性的。我希望附加约束不会对该表的正常插入产生明显影响。
如果 mess_201811.loadedtime 可以为 null,我只能重现它,在这种情况下,必须在附加时扫描它的 NULL 值。如果该列为 NOT NULL,则跳过附件扫描。