缓存表的填充因子是什么?

Mic*_*hal 10 nosql postgresql configuration vacuum fill-factor

我已经大量更新/访问了存储序列化 java 对象的表。它们在表中停留 2-3 小时(在此期间也在更新),然后被删除。表的大小约为 300MB。我发现它非常非常频繁地被 VACUUMed 并想知道改变它fillfactor是否会有所帮助?

Erw*_*ter 17

这里的关键词是:

  1. “大量更新”
  2. “在表2-3小时”。

点 1. 表示填充因子较低,而 2. 则相反。如果多个行版本存储在同一数据页上,则有助于提高性能。热更新将实现这一目标。在此处此处阅读。他们需要在数据页面上有一些回旋余地 - 比如死元组或由fillfactor< 100保留的空间。但他们只能做他们的事情,如果没有索引涉及任何更新的列,这对于你的情况应该是正确的。

这里的另一个重要因素是元组大小(与您的页面大小(最常见的是 8 kb)相比)。此相关答案中的更多详细信息:

如果元组大小为 4 kb 或更大,减少填充因子将是徒劳的,因为数据页上的元组永远不会超过一个。您不妨将其保留为100(无论如何这是默认设置)。但是,如果某些数据类型超过了大小限制,则它们会被“烘烤”并被离线存储,因此在主关系分支中需要那么多的元组很少见。

无论你做什么,VACUUM 都会经常运行。这通常是一件好事,我不会担心。你创建了很多死元组。VACUUM标识对任何打开的事务不再可见的死行。手册:

VACUUM删除表和索引中的死行版本并标记可用空间以供将来重用的标准形式。

大胆强调我的。
您可以使用autovacuum 的per-table 设置减少(或更多)仅针对该表触发它:

默认阈值和比例因子取自 postgresql.conf,但可以逐个表覆盖它们

大胆强调我的。特别是与autovacuum_vacuum_thresholdautovacuum_vacuum_scale_factor。运行VACUUM很多实际上可能是一个好主意,而不是非常低的fillfacter. 这取决于访问模式。如果所有元组都存在,比如说,3 个小时,并且每个元组都更新了几次,我仍然会将其降低fillfactor到 50 之类的值。您必须进行测试并找到最佳点。

备择方案

抛开所有这些,因为您的数据似乎一开始就不稳定:使用UNLOGGED表格

写入未记录表的数据不会写入预写日志(参见第 29 章),这使得它们比普通表快得多。但是,它们不是崩溃安全的:在崩溃或不正常关闭后,未记录的表会自动截断。未记录表的内容也不会复制到备用服务器。

大胆强调我的。如果您的服务器可能崩溃并且之后您仍然需要数据,请不要使用它。但如果我们谈论的是 Web 应用程序的会话数据,这可能是一个可以接受的代价。

或者,甚至更激进:如果可以完全不用 RDBMS 提供的功能和安全性,请使用Redis这样的键值存储