[英]Postgres row_number() doubling table size roughly every 24 hours
我有一个包含 ~165,000 行的 Assets 表。 但是,资产构成“集合”,每个集合可能有大约 10,000 个项目,我想为这些项目保存“排名”,以便用户可以看到给定资产在集合中的排名。
排名可能会发生变化(基于内部分数),因此需要定期更新(每小时几次)。
这是目前在每个集合的基础上完成的:
UPDATE assets a
SET rank = a2.seqnum
FROM
(SELECT a2.*,
row_number() OVER (
ORDER BY elo_rating DESC) AS seqnum
FROM assets a2
WHERE a2.collection_id = #{collection_id} ) a2
WHERE a2.id = a.id;
然而,这导致表的大小大约每 24 小时翻一番(即 1GB 到 2GB)。
VACUUM FULL
这个问题,但这并不是一个真正的解决方案。
是否可以调整查询以不创建太多(我假设是)临时存储?
运行 PostgreSQL 13。
每次更新都会在 Postgres 中写入一个新的行版本。 因此(除了 TOASTed 列)更新表中的每一行都会使其大小加倍。 那就是你观察到的。 死元组稍后可以被清理以缩小表的物理大小 - 这就是VACUUM FULL
所做的,代价高昂。
或者,您可能只是不运行VACUUM FULL
并将表保持在〜最小物理尺寸的两倍。 如果您运行普通的VACUUM
(没有FULL
!)足够 - 如果您没有长时间运行的事务阻塞 - Postgres 将在下一次UPDATE
开始时在可用空间映射中标记死元组并且可以重用磁盘空间,因此保持在其最小尺寸的两倍左右。 这比一直缩小和重新增长表要便宜得多,因为最昂贵的部分通常是物理增长表。
可能更好的是,将排名分解到一个最小的单独 1:1 表中,这样只需“每小时几次”写入最少的行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.