1

我的情景:PostgreSQL的并行BULK INSERT不并行

  • 10个工作
  • 数据库已成立100个最大连接数
  • 每个工人都有自己的数据库连接(最多10个连接。 )
  • 每个工人开始一笔交易(BEGIN; COMMIT;)
  • 每个工人都将数据插入交易中的批量插入同一表中
  • 要插入的数据例如一个百万行
  • 每个工人处理

每个工人的查询1000行(尺寸1000批次):

BEGIN; 
    INSERT INTO "test_tbl" ("id",...) VALUES 
    (...),(...),...[1000 entries]... RETURNING id; 
COMMIT; 

test_tbl只与指数CREATE UNIQUE INDEX formulas_pkey ON formulas USING btree (id)

约束 PRIMARY KEY (id)

问题

经过许多小时的分析后,接线员工等待另一名工人完成插入。为什么工人不能同时将新数据插入同一张表中?

UPDATE

我已经删除了所有的约束和所有索引(主键,外键等),但仍是同样的问题。没有并行化。

补充说明:

  • 数据到例如插入一个百万行
  • 每个工人处理1000行(大小1000的批次)
+0

相似[SO question](http://stackoverflow.com/q/32087233/1835769)。 – displayName

回答

1

,有一个主密钥的事实意味着该数据库有以检查相应的列(多个)是的值UNIQUENOT NULL。开始插入数据的第二个事务在第一个事务尚未完成插入之前无法完成(否则,可能是是非唯一值)。

如果您不想在每个工作人员的交易(但是,批量为100个插入)下进行批量插入,则工作速度会更快。您将需要更多的客户端和数据库之间的电话(您将有n调用与100行数据,而不是非常大的电话与n * 100行);但数据库将能够早日提交。

PostgreSQL

读不会阻塞写,写不会阻塞读

...但交易1 可以(而且经常会)块交易2 还写

如果你不能做批量插入,你可以尝试推迟在transaction.This结束时PRIMARY KEY约束通过定义PRIMARY KEY约束DEFERRABLE INITIALLY DEFERRED(这是不是对PostgreSQL的默认完成的,虽然它是SQL标准)。见documentation for "create table"

DEFERRABLE
NOT DEFERRABLE

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

+0

Thx @joanolo!请阅读我的更新。 – phlegx

+0

你是什么意思:“如果你只是不对每个工人进行1次交易(但是,批量为100个插入)进行批量插入,它将工作得更快。”?我的工作人员在1笔交易中批量插入1000个条目。 – phlegx

+0

这在您的原始文章中并不清楚。所做的更改现在已经清楚了。 – joanolo