我在表上添加新列时遇到问题。
我尝试运行几次,但是运行了十多分钟后,由于锁定时间,我决定取消查询。
ALTER TABLE mytable ADD mycolumn VARCHAR(50);
有用的信息:
- PostgreSQL版本:9.1
- 行数:〜250K
- 列数:38
- 可为空的列数:32
- 约束数量:5(1 PK,3 FK,1 UNIQUE)
- 索引数:1
- 操作系统类型:Debian Squeeze 64
我发现了有关PostgreSQL管理可空列的方式的有趣信息(通过HeapTupleHeader)。
我的第一个猜测是,因为此表已经具有8位的32个可空列MAXALIGN
,所以HeapTupleHeader的长度为4个字节(未经验证,我不知道该怎么做)。
因此,添加新的可为空的列可能需要在每行上更新HeapTupleHeader以添加新的8位MAXALIGN
,这可能会导致性能问题。
因此,我尝试更改可为空的列之一(实际上并不是真正可为空的),以便将可为空的列的数量减少到31,以检查我的猜测是否正确。
ALTER TABLE mytable ALTER myothercolumn SET NOT NULL;
不幸的是,这种更改也需要很长时间,超过5分钟,因此我也中止了它。
您是否知道会导致这种性能损失的原因?
SET NOT NULL
不更改类型,它只是添加一个约束-但是必须对照表检查该约束,这需要全表扫描。9.4通过使用较弱的锁来改进其中一些情况,但是它仍然是重量级的。