【问题标题】:Multiple connections to PostgreSQL with huge number of INSERTs具有大量 INSERT 的多个与 PostgreSQL 的连接
【发布时间】:2014-03-01 01:40:23
【问题描述】:

本题涉及到这个问题:How to speed up insertion performance in PostgreSQL

所以,我有一个 java 应用程序,它正在对PostgreSQL 数据库执行大量(大约十亿)插入操作。它打开几个到同一个数据库的 JDBC 连接,以并行执行这些插入。正如我在提到的问答中所读到的那样:

从多个连接并行插入或复制。多少取决于 在硬件的磁盘子系统上;根据经验,你想要一个 如果使用直连存储,则按物理硬盘驱动器连接。

但就我而言,我的数据库只有 一个磁盘存储

所以,我的问题是:在这种情况下打开多个连接真的有意义吗?由于 I/O 操作竞争,它会降低性能而不是期望的增加吗?

为了澄清,这里是实际postgresql 进程负载的图片:

【问题讨论】:

  • 这取决于磁盘、CPU、处理数据负载所涉及的CPU工作量等。测试一下。一般来说,如果您从两个以上的并发COPY 会话中受益,我会感到惊讶,除非您拥有高性能 SSD。如果您坚持使用INSERTs,那么会有各种各样的开销,所以更多可能会有所帮助。再次,测试并查看。或者更好,切换到COPY
  • @CraigRinger 我不能COPY,因为我正在阅读XML 文件并将其几乎内容推送到bytea 列。以新格式准备这些文件似乎是不可能的。
  • 是的,你可以,你只需要以正确的格式提供输入。如果您不确定,请尝试COPY FROM 转储您已加载少量数据的表;另请查看文档以获取有关格式的详细信息。 postgresql.org/docs/current/static/sql-copy.html 。请记住,您可以使用 CopyManager API 通过 PgJDBC 使用 COPY

标签: postgresql jdbc postgresql-performance


【解决方案1】:

由于您在 Java 应用程序中提到了 INSERT,我假设(使用普通 JDBC)COPY 不是您要寻找的。如果不使用JPA 之类的API 或Spring-data 之类的框架,我可以介绍一下addBatch()executeBatch(),以防您没有听说过这些:

/*
 the whole nine yards
 */
Connection c = ...;
PreparedStatement ps = c.prepareStatement("INSERT INTO table1(columnInt2,columnVarchar)VALUES(?,?)");

然后循环读取数据:

ps.setShort(1, someShortValue);
ps.setString(2, someStringValue);
ps.addBatch();  // one row at a time from human's perspective

当准备好所有行的数据时:

ps.executeBatch();

我也可以推荐一下:

【讨论】:

  • 这是一个非常广泛的答案,它并没有完全涵盖我的情况,并且与 PostgreSQL 的功能无关。
猜你喜欢
  • 2012-01-27
  • 1970-01-01
  • 2012-05-28
  • 2015-11-29
  • 2021-12-19
  • 2017-05-25
  • 1970-01-01
相关资源
最近更新 更多