当我有下表时:
CREATE TABLE test
(
"id" integer NOT NULL,
"myval" text NOT NULL,
CONSTRAINT "test-id-pkey" PRIMARY KEY ("id")
)
执行以下许多查询时:
UPDATE "test" set "myval" = "myval" || 'foobar' where "id" = 12345
然后行myval将随着时间的推移变得越来越大。 postgresql会做什么?从哪里获得空间?
我可以避免postgresql需要多个人寻求阅读特定的myval列吗?
postgresql会自动执行此操作吗?
我知道通常我应该尝试更多地规范化数据。但我需要用一次寻找来读取价值。每次更新(添加数据)时,Myval将放大约20个字节。一些列将有1-2个更新,大约1000个更新。 通常我会使用一个新行而不是更新。但随后选择变慢。 所以我想到了非规范化的想法。
答案 0 :(得分:4)
更改表的FILLFACTOR以为将来的更新创建空间。这也可以是HOT更新,因为文本字段没有索引,以使更新更快并且autovacuum开销更低,因为HOT更新使用微虚拟。 CREATE TABLE语句包含有关FILLFACTOR的一些信息。
ALTER TABLE test SET (fillfactor = 70);
-- do a table rebuild to blow some space in your current table:
VACUUM FULL ANALYZE test;
-- start testing
值70不是完美的设置,它取决于您的独特情况。也许你90岁就可以了,也可能是40岁或者别的什么。
答案 1 :(得分:1)
这与TEXT in PostgreSQL的这个问题有关,或者至少答案是相似的。 PostgreSQL stores large columns远离主表存储:
非常长的值也存储在后台表中,这样它们就不会干扰对较短列值的快速访问。
因此,您可以预期TEXT
(或BYTEA
或大VARCHAR
)列始终远离主表存储,SELECT id, myval FROM test WHERE id = 12345
之类的内容将需要两次搜索将两列从磁盘上拉下来(更多的是寻求解决它们的位置)。
如果您的更新确实导致您的SELECT速度变慢,那么您可能需要查看vacuuming策略。