如果我想要将存储的、生成的列添加到一个非常大的表(100M+行),这将花费不可接受的长时间(处于锁定状态),因为它必须在事务完成之前计算所有行的新列.
希望有一种替代方法可以做到这一点,也许像并发索引或约束,您可以在其中验证列异步.但是,不,似乎没有这样的 Select ,这有点遗憾.
目前,我的计划是使用专用于生成表达式的函数来添加列,其中该函数的初始体将为空,因此具有最小的开销来降低将其应用于所有100M+行的成本.然后,我可以稍后将函数体更新为正确的代码,并让值在整个表中自然更新(我可以手动执行此操作,这是异步的),并等待整个表完成.这肯定不是最理想的.
示例:
CREATE OR REPLACE FUNCTION some_function(
IN TEXT, IN TEXT
) RETURNS TEXT AS
$$
DECLARE
BEGIN
RETURN NULL;
END
$$
LANGUAGE plpgsql
IMMUTABLE
;
ALTER TABLE my_table ADD COLUMN column_c TEXT GENERATED ALWAYS AS ( some_function(column_a, column_b) ) STORED;
CREATE OR REPLACE FUNCTION some_function(
IN TEXT, IN TEXT
) RETURNS TEXT AS
$$
DECLARE
BEGIN
<the actual function code body>
END
$$
LANGUAGE plpgsql
IMMUTABLE
;
<<then some async cursor process that updates all the column_c to their proper values without locking the whole table>>
有没有人知道更好的办法?
[2024-01-21]更新:
我对表的副本(相同的行数,有限的列数)进行了测试,发现上面提出的使用Empty函数的方法需要7分钟来执行;而真正的版本(最终函数)需要14分钟才能执行.虽然真正的交易花费的时间比我担心的要少得多,但空洞的版本并没有什么意义上的不同.我只需要安排一段维修期来做到这一点,并真正做到这一点.
不过,我认为future 需要有一个更好的 Select .