Apache Tomcat JDBC连接池对批处理\批量插入的性能不佳

时间:2015-09-29 15:45:23

标签: java tomcat jdbc bulkinsert jdbc-pool

我最近将Apache Tomcat JDBC连接池合并到我的应用程序中(使用MySQL DB)。我之前尝试过使用Apache DBCP,但不喜欢它的结果,即使我运行一个独立的java应用程序并且根本不使用tomcat,tomcat实现似乎也符合我的需求。

最近,我在执行批量(又称批量)插入查询时遇到了巨大的性能问题。

我有一个流程,我以批量方式将〜2500条记录插入到表中。使用jdbc连接池时需要花费一些时间,相比之下,恢复为每个查询打开连接几秒钟(没有池)。

我写了一个小应用程序,在同一个表中插入了30行。汇集时需要12秒,未汇集时需要约800毫秒。

在使用连接池之前,我使用com.mysql.jdbc.jdbc2.optional.MysqlDataSource作为我的DataSource。连接配置如下:

dataSource.setRewriteBatchedStatements(true);

我非常确定这是两种方法之间的核心差异,但无法在jdbc-pool中找到等效参数。

1 个答案:

答案 0 :(得分:4)

MySql JDBC驱动程序不支持批处理操作。 RewriteBatchedStatement是你能得到的最好的。这里是mysql PreparedStatement.java的代码:

 try {
            statementBegins();

            clearWarnings();

            if (!this.batchHasPlainStatements && this.connection.getRewriteBatchedStatements()) {

                if (canRewriteAsMultiValueInsertAtSqlLevel()) {
                    return executeBatchedInserts(batchTimeout);
                }

                if (this.connection.versionMeetsMinimum(4, 1, 0) && !this.batchHasPlainStatements && this.batchedArgs != null
                        && this.batchedArgs.size() > 3 /* cost of option setting rt-wise */) {
                    return executePreparedBatchAsMultiStatement(batchTimeout);
                }
            }

            return executeBatchSerially(batchTimeout);
        } finally {
            this.statementExecuting.set(false);

            clearBatch();
        }

这是我不喜欢MySql而更喜欢Postgres

的原因之一

编辑:

您应该组合连接池,批处理操作和RewriteBatchedStatement选项。您可以通过jdbc url参数设置RewriteBatchedStatement选项:jdbc:mysql://localhost:3307/mydb?rewriteBatchedStatements=true