我有一个 Postgres 数据库作为应用程序的一部分 目前有文本字段填充了大约 300K 的文本。
表中大约有3列可以常规填充 有了这么多信息。这导致表格结束 大约 100 行的演出。我想删除那些数据 列而不删除行中的其余信息。
UPDATE
将列设置为 ''
是否比 INSERT INTO SELECT
更好,我只选择我需要的列然后 DELETE
现有行?这是第 3 方应用程序,因此目前无法重写它们存储数据的方式。
最佳答案
首先,对于 3 列约 300k 的文本,表格的大小不应超过 1GB,只有 100 行。你有autovacuum
吗启用?或者您是否定期运行吸尘器?了解 vacuum in the manual .检查你的settings .
关于 UPDATE
与 INSERT
/DELETE
的问题:由于 PostgreSQL 的 MVCC model每个 UPDATE
实际上都是一个新的 INSERT
。旧行将被保留并最终被 (auto
)vacuum
清除。 使用UPDATE
,更简单。恢复空间/性能的关键是吸尘。
但是,如果您必须处理所有或大部分行,并且可以独占锁定表(或没有并发访问),则完全重写表会更快,方法是创建一个新表,或者像这样:
还有相关命令CLUSTER
.在完美状态下重写整个表和所有索引。击败 VACUUM FULL
,因为它实际上也是一个 REINDEX
。您可以尝试一次以查看没有死元组的表的实际大小。
关于性能:PostgreSQL 将大列的(压缩)内容写入 TOAST tables .因此,无论列的大小是 30k 还是 30MB,标准查询都执行相同的操作。它只影响检索找到的行的时间。
由于离线(TOASTed)数据也会被压缩,您的表不应超过 1 GB(包括 TOAST 表),即使数据库中的磁盘表示通常占用 2-3 倍的空间原始数据。这通常意味着,您没有清理,大量死元组将您的表弄得乱七八糟。
TOAST 表的一个副作用是 UPDATE
的性能优于 INSERT
/DELETE
because :
During an UPDATE operation, values of unchanged fields are normally preserved as-is; so an UPDATE of a row with out-of-line values incurs no TOAST costs if none of the out-of-line values change.
不过,在您的情况下应该无关紧要,因为您的计划是无论如何都将大列设为 NULL。
关于sql - 更新还是插入和删除?对于大文本列,哪个更适合存储/性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8198786/