【问题标题】:Postgres parallel/efficient load huge amount of data psycopgPostgres 并行/高效加载大量数据 psycopg
【发布时间】:2017-05-14 12:10:46
【问题描述】:

我想从 CSV 文件加载许多行。
文件​s​包含​“article​_name​,​article_time,​start_time,​end_time”​等​数据​

表格有一个约束:对于相同的文章名称,如果新的​article_time落在同一篇文章的现有范围​[start_time,​end_time]​中,我不会插入新行。
即:不插入行 y 如果存在 [​start_time_x,​end_time_x] 其中 time_article_y 在范围 [​start_time_x,​end_time_x] 内,article_​name_​y = article_​name_​x

  • 我尝试使用 psycopg 选择现有的文章名称,并手动检查是否有重叠 --> 太长了
  • 我再次尝试使用 psycopg,这次通过设置条件“排除使用...”并尝试插入指定“冲突时什么也不做”(这样它不会失败)但仍然太长
  • 我尝试了同样的方法,但这次尝试在每次调用 execute (psycopg) 时插入许多值:情况有所好转(在近 10 分钟内处理了 1M 行),但仍然没有达到需要的速度对于我拥有的数据量(500M+)
  • 我尝试通过在不同文件上多次调用同一个脚本来进行并行化,但时间并没有得到任何改善,我猜是因为每次我们想写东西时桌子上都有锁

有没有办法只在包含相同 article_name 的行上创建锁? (而不是整张桌子上的锁?)
您能否提供任何想法以使这种可并行化和/或更节省时间?

​非常感谢大家​

【问题讨论】:

  • 我会先加载整个 csv 然后插入 .. 选择 .. 重叠。复制到没有索引的表将是最快的。对查询而不是复制 csv 的隔离控制尽可能灵活......
  • 感谢 Vao,但同样的问题也会出现。从 csv 加载数据非常快。但是然后通过检查条件转移到表格真的很长。它应该以某种方式可以并行化,但我不知道该怎么做。

标签: postgresql parallel-processing locking load


【解决方案1】:

您的排除约束和INSERT ... ON CONFLICT 的想法很好。

您可以通过以下方式提高速度:

  • 在一个事务中完成所有操作。

  • 就像 Vao Tsun 建议的那样,也许 COPY 先将数据放入一个临时表中,然后使用一条 SQL 语句完成所有操作。

  • 从您修改数据的表中删除除排除约束之外的所有索引,并在完成后重新创建它们。

  • 在加载数据时,通过禁用 autovacuum 并提高 max_wal_size(或在旧 PostgreSQL 版本上提高 checkpoint_segments)来加快插入速度。

【讨论】:

  • 这样,没有并行操作吧?这对于 100 万行来说是可以的,但对于数以亿计的行来说绝对是耗时的。
  • 我不知道并行化是否能给你带来很多好处,而且你的实验似乎表明收益相当有限。我想不出比并行运行多个 INSERT .. ON CONFLICT 语句(处理不同的输入数据)更好的方法了。我想限制因素是您的病情的相对复杂性。
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多