缓存表的填充因子是多少?


10

我有大量更新/访问的表,其中存储了序列化的Java对象。它们在表中停留了2-3个小时(在此期间也正在更新),然后将其删除。表的大小约为300MB。我发现它经常被抽空,想知道改变它fillfactor是否有帮助?

Answers:


17

这里的关键词是:

  1. “大量更新”
  2. “在桌子上待了2-3个小时”。

点1.表示较低的填充系数,而点2.相反。如果多个行版本存储在同一数据页上,则有助于提高性能。HOT更新将实现这一目标。在这里这里阅读。他们需要在数据页上留出一些摆动的空间,例如死元组或fillfactor<100 保留的空间。但是,如果没有索引涉及任何更新的列,它们只能做自己的事情,这对于您的情况应该是正确的。

另一个重要因素是元组大小(与页面大小相比(通常为8 kb)。有关此答案的更多详细信息:

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

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

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

大胆强调我的。
您可以使用针对每个表的自动真空设置仅在此表上触发更少(或更多)的自动真空

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

大胆强调我的。特别是autovacuum_vacuum_thresholdautovacuum_vacuum_scale_factorVACUUM大量运行实际上是一个好主意,而不是一个很低的水平fillfacter。这取决于访问模式。如果所有元组都生存了3个小时,并且每个元组都更新了几次,那么我仍然会将其降低fillfactor到50个左右。

备择方案

除了所有这些之外,由于您的数据一开始似乎是易变的:使用UNLOGGED

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

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

或更彻底的是:如果可以完全不使用RDBMS提供的功能和安全性,则可以使用Redis这样的键值存储


我认为未记录的正是我需要的
米哈尔

0

我建议使用键值DBMS,但是出于兴趣的考虑,我将其丢弃。

而不是执行INSERT&DELETE语句,而是执行UPDATE。

该表的结构将类似于

ID      integer  -- sequential ID
Used    boolean  -- default FALSE
Object  -- whatever type is appropriate

对象保持列的长度将固定,以避免拆分和行移动。调整此列的大小以容纳您的对象并有效地填充磁盘上的页面。

在表中预填充所需的行数,然后再添加几行。

当要写一个对象时,找到Used = False的一行并更新该行。当物体要被销毁时,将其设置为“ False”。没有创建垃圾,因此也没有垃圾收集。

当然,要处理的异常条件很多(行溢出,表溢出,ID使用的竞争条件等),但是没有一个是无法克服的。


据我了解,除非是HOT更新,否则这些UPDATE通常仍会将行的全新副本写入磁盘。因此,随着时间的流逝,您仍然最终需要GC /抽真空。
杰夫·威德曼
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.