Postgresql自动清空花费的时间太长

Postgresql自动清空花费的时间太长,postgresql,vacuum,Postgresql,Vacuum,我有一个db表,它有大约5-6MN个条目,执行吸尘大约需要20分钟。由于此表的一个字段更新非常频繁,因此需要处理大量死行 据估计,根据我们目前的用户群,它每天可能有200万个死元组。因此,对该表进行真空处理需要: 读取IO:因为整个表不在共享内存中 写IO:因为有很多条目需要更新 用真空吸尘器清理桌子的理想方法是什么?我是否应该增加autovacuum\u成本\u限制以允许每次自动真空运行进行更多操作?但正如我所看到的,它将增加IOPS,这可能会再次阻碍性能。目前,我有autovacuum\u

我有一个db表,它有大约5-6MN个条目,执行吸尘大约需要20分钟。由于此表的一个字段更新非常频繁,因此需要处理大量死行

据估计,根据我们目前的用户群,它每天可能有200万个死元组。因此,对该表进行真空处理需要:

  • 读取IO:因为整个表不在共享内存中
  • 写IO:因为有很多条目需要更新
  • 用真空吸尘器清理桌子的理想方法是什么?我是否应该增加
    autovacuum\u成本\u限制
    以允许每次自动真空运行进行更多操作?但正如我所看到的,它将增加
    IOPS
    ,这可能会再次阻碍性能。目前,我有
    autovacuum\u scale\u factor=0.2
    。我应该减少吗?如果我减少它,它会运行得更频繁,虽然写IO会减少,但它会导致更多的时间段和高读IO

    此外,随着用户基数的增加,随着表格大小的增加和真空度的增加,需要从磁盘读取大量数据,这将花费越来越多的时间。那么,我该怎么办

    我想到的解决方案之一是:

  • 将高度更新的列分隔开,并创建一个单独的表
  • 调整参数使其更频繁地运行以减少写入IO(如上所述)。如何处理更多的读取IO,因为真空将更频繁地运行
  • 将第2点与增加RAM结合起来,以减少读取IO

  • 一般来说,人们采取的方法是什么,因为我假设人们必须有非常大的10GB或更大的表,需要进行真空吸尘。

    有两种方法:

  • 减少该表的
    autovacuum\u vacuum\u成本\u延迟
    ,使autovacuum变得更快。它仍将消耗I/O、CPU和RAM

  • 将表的
    fillfactor
    设置为小于100的值,并确保经常更新的列没有索引。然后,您可以获得不需要
    VACUUM
    的热更新


  • 有两种方法:

  • 减少该表的
    autovacuum\u vacuum\u成本\u延迟
    ,使autovacuum变得更快。它仍将消耗I/O、CPU和RAM

  • 将表的
    fillfactor
    设置为小于100的值,并确保经常更新的列没有索引。然后,您可以获得不需要
    VACUUM
    的热更新


  • 分离纵队是一个可行的策略,但对我来说是最后的选择。PostgreSQL已经具有很高的每行开销,这样做会使其增加一倍(这也可能会消除大部分好处)。另外,它会使您的查询更难看、更难阅读、更难维护、更容易引入bug。如果只对一组列进行索引扫描,而不包括对您来说很重要的列,那么拆分它最有吸引力,并且拆分它可以使其余列的可见性映射保持在更好的状态

    你为什么在乎20分钟?这是不是导致了一些不好的事情发生?按照这个速度,你可以每天用吸尘器清理这张桌子72次,这似乎比实际需要清理的次数要多得多。在v12中,自动真空成本延迟的默认值降低了10倍,降至2ms。默认值的这种变化不是由v12中代码的变化驱动的,而是因为认识到在大多数情况下,旧的默认值与现代硬件已经过时。我将毫无困难地将更改推到v11配置中;但我认为这样做也不能解决你的主要担忧

    您是否真的对生成的IO数量有问题,或者只是猜测?IO的完成主要是按顺序进行的,但其重要性取决于您的存储硬件。当真空发生时,您是否看到延迟峰值?您是否按IO收费,账单是否过高?高IO本身不是一个问题,只有在它导致问题时才是一个问题

    目前,我有自动真空比例系数=0.2。我应该减少吗? 如果我减少它,它会运行得更频繁,尽管写IO会 减少,但会导致更多的时间段和高读取 木卫一


    更频繁地运行可能不会使您的写入IO减少很多(如果有的话)。每个表/索引页至少有一个过时的元组需要在每次真空期间写入。编写一个页面只是为了删除一个过时的元组,而不是等到有很多过时的元组可以通过一次写入全部删除,这会导致更多的写入。你可能会在每个真空中写得少一些,但做更多的真空将弥补这一点,而且可能远远超过弥补这一点。

    分离专栏是一个可行的策略,但对我来说是最后的手段。PostgreSQL已经具有很高的每行开销,这样做会使其增加一倍(这也可能会消除大部分好处)。另外,它会使您的查询更难看、更难阅读、更难维护、更容易引入bug。如果只对一组列进行索引扫描,而不包括对您来说很重要的列,那么拆分它最有吸引力,并且拆分它可以使其余列的可见性映射保持在更好的状态

    你为什么在乎20分钟?这是不是导致了一些不好的事情发生?按照这个速度,你可以每天用吸尘器清理这张桌子72次,这似乎比实际需要清理的次数要多得多。在v12中,自动真空成本延迟的默认值降低了10倍,降至2ms。默认值的这种变化不是由v12中代码的变化驱动的,而是因为认识到在大多数情况下,旧的默认值与现代硬件已经过时。我将毫无困难地将更改推到v11配置中;但我认为这样做也不能解决你的主要担忧

    溜溜球