首页 > 解决方案 > Postgres Upsert - 碎片问题

问题描述

概括

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

语境

我每小时将批量 ETL 更新插入到表中(表 ~ 数百万,upsert ~ 数万),并且我们在 AWS 上将自动真空设置为阈值。

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

问题!

Upsert 是否从根本上对碎片化产生负面影响,如果是,其他人在使用什么?我热衷于实现一些物化视图并将我们的大部分索引移动到新视图,同时只保留我们正在写入的表上的 PK 索引,但我不相信这会解决我看到的膨胀问题.

我已经对该问题进行了一些阅读,但没有任何结论,例如 --> https://www.targeted.org/articles/databases/fragmentation.html

谢谢你的帮助

标签: postgresqlamazon-rdsdatabase-administrationupsertvacuum

解决方案


这取决于。如果没有违反约束,INSERT ... ON CONFLICT不会导致任何膨胀。如果它执行更新,它将产生一个死行。

您可以采取的措施:

  • 设置autovacuum_vacuum_cost_delay = 0为更快的自动真空

  • 使用fillfactor略小于 100 并且在更新的列上没有索引,以便您可以获得 HOT 更新,这使得 autovacuum 不必要


推荐阅读