为什么Spring的jdbcTemplate.batchUpdate()这么慢?

问题描述 投票:0回答:2

我正在尝试找到更快的方法来进行批处理插入

我尝试使用 jdbcTemplate.update(String sql) 插入多个批次,其中 sql 由 StringBuilder 构建,如下所示:

INSERT INTO TABLE(x, y, i) VALUES(1,2,3), (1,2,3), ... , (1,2,3)

批量大小正好是1000。我插入了近100个批次。 我使用秒表检查了时间并找出了插入时间:

min[38ms], avg[50ms], max[190ms] per batch

我很高兴,但我想让我的代码变得更好。

之后,我尝试以如下方式使用jdbcTemplate.batchUpdate:

    jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
                       // ...
        }
        @Override
        public int getBatchSize() {
            return 1000;
        }
    });

sql 看起来像这样

INSERT INTO TABLE(x, y, i) VALUES(1,2,3);

我很失望! jdbcTemplate 以单独的方式批量执行 1000 行的每一次插入。我查看了 mysql_log,发现有一千个插入。 我使用秒表检查了时间并找出了插入时间:

每批次最小[900ms],平均[1100ms],最大[2000ms]

那么,有人可以向我解释一下,为什么 jdbcTemplate 在这个方法中进行分离插入吗?为什么方法的名称是batchUpdate? 或者我可能以错误的方式使用这种方法?

java mysql spring spring-batch jdbctemplate
2个回答
29
投票

JDBC 连接 URL 中的这些参数可以对批处理语句的速度产生很大影响 --- 根据我的经验,它们可以加快速度:

?useServerPrepStmts=false&rewriteBatchedStatements=true

参见:JDBC批量插入性能


28
投票

我发现了重大改进在调用中设置argTypes数组。

在我的例子中,使用 Spring 4.1.4 和 Oracle 12c,插入 5000 行和 35 个字段:

jdbcTemplate.batchUpdate(insert, parameters); // Take 7 seconds

jdbcTemplate.batchUpdate(insert, parameters, argTypes); // Take 0.08 seconds!!!

argTypes 参数是一个 int 数组,您可以通过以下方式设置每个字段:

int[] argTypes = new int[35];
argTypes[0] = Types.VARCHAR;
argTypes[1] = Types.VARCHAR;
argTypes[2] = Types.VARCHAR;
argTypes[3] = Types.DECIMAL;
argTypes[4] = Types.TIMESTAMP;
.....

我调试了 org\springframework\jdb

© www.soinside.com 2019 - 2024. All rights reserved.