带有工人的PostgreSQL并行批量INSERT不并行化

phl*_*egx 2 postgresql parallel-processing multithreading bulkinsert sql-insert

我的情况:

  • 10名工人
  • 数据库已设置100个最大连接
  • 每个工人都有自己的数据库连接(最多10个连接)
  • 每个工作人员开始一个事务(开始;提交;)
  • 每个工作人员将数据插入同一表中,并在事务内批量插入
  • 要插入的数据,例如一百万行
  • 每个工人处理1000行(每批次1000个)

每个工人的查询:

BEGIN;
  INSERT INTO "test_tbl" ("id",...) VALUES 
    (...),(...),...[1000 entries]... RETURNING id;
COMMIT;
Run Code Online (Sandbox Code Playgroud)

test_tblPRIMARY KEY (id)具有索引约束CREATE UNIQUE INDEX formulas_pkey ON formulas USING btree (id)

问题

经过许多小时的分析,它接缝的是工人等另一个工人完成了插入。为什么工人不能同时将新数据插入同一张表?

更新

我删除了所有约束和所有索引(主键,外键等),但仍然存在相同的问题。没有并行化。

补充说明:

  • 要插入的数据,例如一百万行
  • 每个工人处理1000行(每批次1000个)

joa*_*olo 5

有一个主密钥的装置,所述数据库具有以检查相应的列(多个)的值的事实是UNIQUENOT NULL。在第一个事务尚未完成插入之前,第二个开始插入数据的事务将无法执行此操作(否则,可能存在非唯一值)。

如果您只是不为每个工作人员执行1次事务中的批量插入操作(但是,可以说,批量处理100次插入操作),它将更快地工作。您将需要在客户端和数据库之间进行更多调用(您将有n个具有100行数据的调用,而不是1个具有n * 100行的非常大的调用);但是数据库将能够提早提交。

PostgreSQL中

阅读永远不会阻止写作,写作永远不会阻止阅读

...但是事务1的写入可以(并且经常会)阻止事务2的写入

如果你不能做批量插入,你可以尝试推迟PRIMARY KEY在transaction.This结束约束通过定义进行PRIMARY KEY约束DEFERRABLE INITIALLY DEFERRED(这是不是对PostgreSQL默认的,虽然它是SQL标准)。请参阅“创建表”文档

DEFERRABLE
NOT DEFERRABLE

这控制是否可以推迟约束。在每个命令之后,将立即检查不可延迟的约束。可以推迟检查约束,直到事务结束为止(使用SET CONSTRAINTS命令)。默认值是NOT DEFERRABLE。当前,只有UNIQUE,PRIMARY KEY,EXCLUDE和REFERENCES(外键)约束接受此子句。