问题标签 [large-scale]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
postgresql - 将大量行插入单个表的最佳方法是什么?
我正在开发一种产品,该产品涉及到单个表中的大量 upsert 操作。
我们正在处理基于时间的数据并使用具有 7 天块间隔大小的 timescaledb 超表。我们有并发任务,将数据更新插入到单个表中,在极端情况下,我们可能会有 40 个并发任务,每个更新插入大约 250k 行,全部到同一个表中。
最初我们决定采用删除所有旧行然后使用COPY FROM
语句插入更新的方法的方法,但是当我们要大规模测试系统时,这些COPY
s需要很长时间才能完成,最终导致db的CPU使用率达到 100%,并且变得没有反应。我们还注意到,表的索引大小急剧增加,磁盘使用率达到 100%,SELECT
语句执行时间极长(超过 10 分钟)。我们得出结论,其原因是大量删除语句导致索引碎片,并决定采用另一种方法。
按照这篇文章的答案,我们决定将所有数据复制到一个临时表中,然后使用“扩展插入”语句将所有数据插入到实际表中 -
我们的测试表明它有助于解决索引碎片问题,但大约 250K 的大型 upsert 操作仍然需要超过 4 分钟才能执行,并且在此 upsert 过程中SELECT
语句需要太长时间才能完成,这对我们来说是不可接受的。
我想知道创建此 upsert 操作的最佳方法是什么,对SELECT
s 的性能影响尽可能低。现在唯一想到的是将插入分成更小的块 -
但是如果我们批量插入,首先将所有数据复制到临时表中有什么好处吗?它会比简单的多行插入语句执行得更好吗?以及如何确定拆分 upsert 时使用的最佳块大小是多少?是否使用临时表并直接从中插入行允许更大的块大小?
有没有更好的方法来实现这一目标?任何建议将不胜感激