Postgresql parallel bulk INSERT with worker 不并行化
Postgresql parallel bulk INSERT with worker don't parallelize
我的场景:
- 10 名工人
- 数据库已设置 100 个最大连接数
- 每个工作人员都有自己的数据库连接(最多 10 个连接)
- 每个 worker 启动一个事务 (BEGIN; COMMIT;)
- 每个工作人员都在同一个 table 中插入数据,并在事务中进行批量插入
- 要插入的数据,例如100 万行
- 每个工作人员处理 1000 行(批量大小为 1000)
每个工人的查询:
BEGIN;
INSERT INTO "test_tbl" ("id",...) VALUES
(...),(...),...[1000 entries]... RETURNING id;
COMMIT;
Table test_tbl
只有索引 CREATE UNIQUE INDEX formulas_pkey ON formulas USING btree (id)
的约束 PRIMARY KEY (id)
问题
经过几个小时的分析,接缝是工人在等待另一个工人完成插入。为什么worker不能同时向同一个table插入新数据?
更新
我已经删除了所有约束和所有索引(主键、外键等),但仍然是同样的问题。没有并行化。
添加注释:
- 要插入的数据,例如100 万行
- 每个工作人员处理 1000 行(批量大小为 1000)
存在主键的事实意味着数据库必须检查相应列的值是否为 UNIQUE
和 NOT NULL
。第二个开始插入数据的事务要等到第一个事务还没有完成插入(否则,可能是non-unique个值)。
如果您只是不对每个工作人员在 1 个事务中执行批量插入(但是,比方说,批量插入 100 个),它会工作得更快。您将需要在客户端和数据库之间进行更多调用(您将使用 n 调用 100 行数据,而不是使用 1 非常大的调用 n*100 行);但数据库将能够更早提交。
在PostgreSQL中:
reading never blocks writing and writing never blocks reading
...但是事务 1 写 可以(而且经常会)阻止事务 2 也写。
如果您不能进行批量插入,您可以尝试延迟 transaction.This 末尾的 PRIMARY KEY
约束是通过定义您的 PRIMARY KEY
约束 DEFERRABLE INITIALLY DEFERRED
(这不是 PostgreSQL 的默认值,尽管它是 SQL 标准)。见 documentation for "create table":
DEFERRABLE
NOT DEFERRABLE
This controls whether the constraint can be deferred. A constraint that is not deferrable will be checked immediately after every command. Checking of constraints that are deferrable can be postponed until the end of the transaction (using the SET CONSTRAINTS command). NOT DEFERRABLE is the default. Currently, only UNIQUE, PRIMARY KEY, EXCLUDE, and REFERENCES (foreign key) constraints accept this clause.
我的场景:
- 10 名工人
- 数据库已设置 100 个最大连接数
- 每个工作人员都有自己的数据库连接(最多 10 个连接)
- 每个 worker 启动一个事务 (BEGIN; COMMIT;)
- 每个工作人员都在同一个 table 中插入数据,并在事务中进行批量插入
- 要插入的数据,例如100 万行
- 每个工作人员处理 1000 行(批量大小为 1000)
每个工人的查询:
BEGIN;
INSERT INTO "test_tbl" ("id",...) VALUES
(...),(...),...[1000 entries]... RETURNING id;
COMMIT;
Table test_tbl
只有索引 CREATE UNIQUE INDEX formulas_pkey ON formulas USING btree (id)
PRIMARY KEY (id)
问题
经过几个小时的分析,接缝是工人在等待另一个工人完成插入。为什么worker不能同时向同一个table插入新数据?
更新
我已经删除了所有约束和所有索引(主键、外键等),但仍然是同样的问题。没有并行化。
添加注释:
- 要插入的数据,例如100 万行
- 每个工作人员处理 1000 行(批量大小为 1000)
存在主键的事实意味着数据库必须检查相应列的值是否为 UNIQUE
和 NOT NULL
。第二个开始插入数据的事务要等到第一个事务还没有完成插入(否则,可能是non-unique个值)。
如果您只是不对每个工作人员在 1 个事务中执行批量插入(但是,比方说,批量插入 100 个),它会工作得更快。您将需要在客户端和数据库之间进行更多调用(您将使用 n 调用 100 行数据,而不是使用 1 非常大的调用 n*100 行);但数据库将能够更早提交。
在PostgreSQL中:
reading never blocks writing and writing never blocks reading
...但是事务 1 写 可以(而且经常会)阻止事务 2 也写。
如果您不能进行批量插入,您可以尝试延迟 transaction.This 末尾的 PRIMARY KEY
约束是通过定义您的 PRIMARY KEY
约束 DEFERRABLE INITIALLY DEFERRED
(这不是 PostgreSQL 的默认值,尽管它是 SQL 标准)。见 documentation for "create table":
DEFERRABLE
NOT DEFERRABLE
This controls whether the constraint can be deferred. A constraint that is not deferrable will be checked immediately after every command. Checking of constraints that are deferrable can be postponed until the end of the transaction (using the SET CONSTRAINTS command). NOT DEFERRABLE is the default. Currently, only UNIQUE, PRIMARY KEY, EXCLUDE, and REFERENCES (foreign key) constraints accept this clause.