Thi*_*yen 12 postgresql performance sequence update
将 BIGSERIAL 列添加到大表(约 3 Bil. 行,约 174Gb)的最快方法是什么?
编辑:
NOT NULL
) 的递增值。Erw*_*ter 13
有什么问题:
ALTER TABLE foo ADD column bar bigserial;
Run Code Online (Sandbox Code Playgroud)
将自动填充唯一值(从 1 开始)。
如果您希望每个现有行都有一个数字,则必须更新表中的每一行。或者你没有?
如果它不能重用死元组或数据页上的可用空间,该表将膨胀到其大小的两倍。操作的性能可能会从FILLFACTOR
低于 100 或只是散布在表上的随机死元组中受益很多。否则,您可能希望在VACUUM FULL ANALYZE
之后运行以恢复磁盘空间。不过,这不会很快。
pgstattuple
您可能对此扩展感兴趣。它可以帮助您收集有关表格的统计信息。要了解死元组和可用空间:
每个数据库安装一次扩展:
CREATE EXTENSION pgstattuple;
Run Code Online (Sandbox Code Playgroud)
称呼:
SELECT * FROM pgstattuple('tbl');
Run Code Online (Sandbox Code Playgroud)
如果您有能力创建一个新表,这会破坏依赖的视图、外键、...
创建旧表的空副本:
CREATE new_tbl AS
SELECT *
FROM old_tbl
LIMIT 0;
Run Code Online (Sandbox Code Playgroud)
添加 bigserial 列:
ALTER new_tbl ADD column bar bigserial;
Run Code Online (Sandbox Code Playgroud)
从旧表插入数据,自动填充 bigserial:
INSERT INTO new_tbl
SELECT * -- new column will be filled with default
FROM old_tbl
ORDER BY something; -- or don't order if you don't care: faster
Run Code Online (Sandbox Code Playgroud)
INSERT 的 SELECT 中缺少新的 bigserial 列,将自动填充其默认值。您可以拼出所有列并将其添加nextval()
到SELECT
列表中以达到相同的效果。
确保您在新表中获得了所有数据。
添加索引,约束,你在旧表有触发器现在。
DROP TABLE old_tbl;
ALTER TABLE new_tbl RENAME TO old_tbl;
Run Code Online (Sandbox Code Playgroud)
整体上可能会快一些。这让您拥有一个没有任何膨胀的普通表(和索引)。
您需要可用磁盘空间 - 大约是旧表的大小,具体取决于表的状态 - 作为摆动空间。但是由于表膨胀,您可能需要使用第一种简单方法。同样,详细信息取决于表的状态。
归档时间: |
|
查看次数: |
28447 次 |
最近记录: |