jdbc批处理性能

wut*_*aer 2 postgresql performance jdbc batch-file

我正在使用jdbc批量更新

ps = con.prepareStatement("");
ps.addBatch();
ps.executeBatch();
Run Code Online (Sandbox Code Playgroud)

但在后台看来,prostgres驱动程序将查询一点一点地发送到数据库.

org.postgresql.core.v3.QueryExecutorImpl:398

 for (int i = 0; i < queries.length; ++i)
            {
                V3Query query = (V3Query)queries[i];
                V3ParameterList parameters = (V3ParameterList)parameterLists[i];
                if (parameters == null)
                    parameters = SimpleQuery.NO_PARAMETERS;

                sendQuery(query, parameters, maxRows, fetchSize, flags, trackingHandler);

                if (trackingHandler.hasErrors())
                    break;
            }
Run Code Online (Sandbox Code Playgroud)

有没有可能让他送1000次加速呢?

Cra*_*ger 9

AFAIK在fe/be协议中没有服务器端批处理,因此PgJDBC无法使用它..更新:嗯,我错了.PgJDBC(从9.3开始准确的)如果不需要获取生成的密钥,它会向服务器发送批量查询.它只是在发送缓冲区中排队一堆查询,而不是在每次单独查询后与服务器同步.

看到:

即使在请求生成密钥时,也使用扩展查询协议来确保每次都不需要发送查询文本,只需要发送参数.

坦率地说,JDBC批处理在任何情况下都不是一个很好的解决方案.它对于应用程序开发人员来说很容易使用,但是对于性能来说非常不理想,因为服务器仍然必须单独执行每个语句 - 尽管不是解析并且只要您使用预准备语句就可以单独计划它们.

如果启用了自动提交,则性能将完全可悲,因为每个语句都会触发提交.即使你可以消除往返延迟,即使自动提交关闭运行许多小语句也不会特别快.

对于许多简单的UPDATEs,更好的解决方案可以是:

  • COPY新数据到表TEMPORARYUNLOGGED表中; 和
  • 使用UPDATE ... FROMUPDATEJOIN对复制表

对于抄见的PgJDBC文档,并COPY服务器中的文档文件.

您经常会发现调整内容是可能的,因此您的应用根本不需要发送所有这些内容UPDATE.