许多小插入-更好地将它们分批处理或使用准备好的语句?

时间:2019-04-05 05:10:34

标签: sql postgresql prepared-statement sql-insert bulkinsert

我正在运行一个软件,该软件可生成大约几百万个小数据,并需要尽快将它们放入数据库中。

这时候我正在使用准备好的语句,并为小插入优化了数据库(Postgres 9.6),并获得了相当不错的性能。但是我想知道,如果不是代替准备好的语句而是对数据进行批处理,这样我就不会单独插入每一行,是否会进一步加快处理速度。

我已经对该问题进行了一些研究,但没有得出结论性的答案。

我的数据相当小(每行5-10个值),并且纯数字形式(即没有字符串,而是整数,浮点数和布尔值的混合)。我的表使用序列作为主键,但没有其他索引。我正在插入通过外键链接的多个表。目前,我有五个准备好的语句,每个表一个。每个语句插入一行,因为我无法提前告知我将获得多少行。

我的陈述是微不足道的-没有数学,条件或任何东西,基本上它们都是这样的:

conn.prepare("INSERT INTO event 
(sc_id, r_id, th_id, tc, rs, is_te, is_le, total) 
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) 
RETURNING id")

我在已经进行基准测试的快速存储上使用了Postgresql 9.6,发现这不是瓶颈。我的软件是用Rust编写的,其生成数据的速度比数据库存储数据快两个数量级。通过优化Postgres配置,我的性能已经提高了4倍,我认为这将是我获得的大部分收益。

我也在并行线程中运行,每个线程都插入彼此独立的数据集。

DB服务器与数据生成器位于同一台物理计算机上,我通过套接字而不是TCP进行连接。

1 个答案:

答案 0 :(得分:0)

通过多行插入可以获得一些好处:

INSERT INTO xyz (col1, col2, ...) VALUES
   (...),
   (...),
   ...

这样做的好处是,客户端-服务器之间的往返次数更少。

但是最快的方法是使用COPY语句。这样,您可以从数据库计算机上的文件或通过客户端连接加载数据。

如果所有这些都不会使您的I / O子系统饱和,请在多个数据库会话中并行插入数据。