Postgresql Postgres Upsert-碎片化问题

Postgresql Postgres Upsert-碎片化问题,postgresql,amazon-rds,database-administration,upsert,vacuum,Postgresql,Amazon Rds,Database Administration,Upsert,Vacuum,摘要 我在ETL中使用Postgres UPSERTs,我正在写入的表上遇到碎片和膨胀问题,这会减慢包括读取在内的所有操作 上下文 我有每小时一次的批量ETL上传到表格中(表格~100万,上传~10万),我们在AWS上有自动真空设置为阈值 我不得不运行全真空,以恢复空间并防止进程挂起。现在,随着一个ETL的频率增加,这种情况变得更加严重,它填充了一些核心表,这些核心表是许多非规范化视图的来源。 似乎正在发生的事情是,在下一次ETL运行之前,表没有机会被清空,因此产生了一个螺旋,最终导致完全减速

摘要

我在ETL中使用Postgres UPSERTs,我正在写入的表上遇到碎片和膨胀问题,这会减慢包括读取在内的所有操作

上下文


我有每小时一次的批量ETL上传到表格中(表格~100万,上传~10万),我们在AWS上有自动真空设置为阈值

我不得不运行全真空,以恢复空间并防止进程挂起。现在,随着一个ETL的频率增加,这种情况变得更加严重,它填充了一些核心表,这些核心表是许多非规范化视图的来源。 似乎正在发生的事情是,在下一次ETL运行之前,表没有机会被清空,因此产生了一个螺旋,最终导致完全减速

问题

Upsert从根本上对碎片化有负面影响吗?如果有,其他人在使用什么?我渴望实现一些具体化视图,并将我们的大多数索引移动到新视图,同时只保留我们正在写入的表上的PK索引,但我不相信这会解决我所看到的膨胀问题

我对这个问题做了一些阅读,但没有任何结论,例如-->


谢谢你的帮助,视情况而定。如果没有违反约束,
INSERT。。。冲突时
不会导致任何膨胀。如果它执行更新,它将生成一个死行

您可以采取的措施:

  • autovacuum\u vacuum\u cost\u delay=0设置为更快的自动真空

  • 使用略小于100的
    fillfactor
    ,并且在更新的列上没有索引,这样您就可以获得热更新,这使得自动真空变得不必要


    • 不清楚你到底看到了什么。您是否可以打开track\u io\u timing,然后对您认为因膨胀而减慢的查询执行
      解释(分析,缓冲)

      膨胀和碎片不是一回事。在某些情况下,碎片更多的是索引的问题,而不是表本身的问题

      似乎正在发生的是,在下一次ETL运行之前,表没有机会被清空


      这个可能很容易修复。在每次ETL运行结束或开始时运行“手动”真空(非真空满)。由于您有一个定义良好的工作流,因此无需尝试让autovacuum执行正确的操作,因为将手动真空注入到您的工作流中应该非常容易。或者你认为每个ETL一个真空度是过分的吗?

      @LaurenzAlbe给出了以下很好的建议。此外,请确保没有长时间运行的事务会阻止autovacuum清理表。“auto vacuums set to thresholds”这意味着什么?@jjanes我的意思是,在AWS中,真空阈值是适当设置的。具有非常低比例因子的大型表,具有合理的阈值,以避免必须对小型表进行真空处理。