我想在1000多万条记录的大表上增加数字列的精度。标准方式ALTER TABLE mytable ALTER COLUMN mycolumn TYPE numeric(15,6)
将锁定表。这是一个高度交易的表。有没有办法在不锁定表并且不重新创建表,复制数据以及重命名/交换表的情况下执行此操作?我目前正在运行一个码头化的postgres 9.5
答案 0 :(得分:1)
我没有想过更改typmod需要一个完整的表重写,但是快速检查表明如果你在finish_heap_swap
中设置一个断点,它实际上会对像{{{cmd}这样的cmd进行重写。 1}} - 至少在9.5。
编辑: a_horse_with_no_name 指出只有在更改精度而不是比例时才会执行重写。所以你可以用一个短暂的独占锁来做到这一点,它不会大大破坏操作。
否则:
您可能会欺骗并直接更新系统目录,因为您知道新精度对旧精度的所有行都有效。但是我有点犹豫,因为如果这很简单,可能PostgreSQL已经做到了。我不推荐它,但如果你想进行实验,测试,做一些阅读等,你可以从那里开始。
对于列ALTER TABLE test_numeric ALTER COLUMN x TYPE numeric(8,4)
的表test_numeric
:
x numeric(4,2)
如果我test=> select atttypmod from pg_attribute where attrelid = 'test_numeric'::regclass AND attname = 'x';
atttypmod
-----------
262150
(1 row)
到ALTER
:
15,6
(我无法阅读typmod的代码,看看如何将32位typmod字段分解为精度和比例,但如果你愿意,你可以。)
应该<{1}}使用新的atttypmod安全test=> select atttypmod from pg_attribute where attrelid = 'test_numeric'::regclass AND attname = 'x';
atttypmod
-----------
983050
(1 row)
条目。但正如我所说的那样,先做一些阅读和研究,看看你是否能找到关于直接typmod更新的事先讨论。
任何适用于延长UPDATE
的内容也适用于pg_attribute
,因为两者都是VARCHAR(n)
内部存储类型,并且都有typmod,其中较大的值是较小值的纯超集。您可能会发现更多关于人们在没有重写的情况下延长NUMERIC
的信息。