Java mysql jdbc即使在重写BatchedStatements=true之后也不会批处理查询

Java mysql jdbc即使在重写BatchedStatements=true之后也不会批处理查询,java,mysql,jdbc,spring-boot,amazon-rds,Java,Mysql,Jdbc,Spring Boot,Amazon Rds,我一直在互联网上阅读关于为什么jdbc批量更新如此缓慢的文章。看起来正确的修复方法是在连接字符串中设置rewriteBatchedStatements=true。但我似乎无法让它为我工作 我正在使用springboot和SpringJDBC 在my application.properties中,Ive设置rewriteBatchedStatements=true spring.datasource.url=jdbc:mysql://RDS_URL.us-west-2.rds.amazonaws

我一直在互联网上阅读关于为什么jdbc批量更新如此缓慢的文章。看起来正确的修复方法是在连接字符串中设置
rewriteBatchedStatements=true
。但我似乎无法让它为我工作

我正在使用springboot和SpringJDBC 在my application.properties中,Ive设置rewriteBatchedStatements=true

spring.datasource.url=jdbc:mysql://RDS_URL.us-west-2.rds.amazonaws.com/DATABASE?rewriteBatchedStatements=true
我还设置了一个断点来验证代码中是否反映了
?rewriteBatchedStatements=true

我将general_log设置为true,在查看日志时,我发现插入没有正确地进行批处理

这就是我的sql字符串的样子

private static String INSERT_USER_TO_GROUP_SQL=“INSERT INTO users(groupId、phoneNumber、accountId、source)值(?,,?,?)”;

日志中的行都是这样的

45查询插入用户(groupId、phoneNumber、accountId、source)值('49','99999999','123','web')

我的批插入java代码是

executor.submit(() -> {
  jdbcTemplate.batchUpdate(INSERT_USER_TO_GROUP_SQL, new BatchPreparedStatementSetter() {

    @Override
    public void setValues(PreparedStatement ps, int i) throws SQLException {
      Subscriber subscriber = subscribers.get(i);
      ps.setString(1, subscriberGroup.getGroupId());
      ps.setString(2, subscriber.getPhoneNumber());
      ps.setString(3, accountId);
      ps.setString(4, subscriberGroup.getSource());
    }

    @Override
    public int getBatchSize() {
      return subscribers.size();
    }

  }); // end BatchPreparedStatementSetter lambda class
}); // end thread
下面是方法
batchUpdate
的一个片段,如下所示,它调用addBatch(),最后调用executeBatch()

此外,我甚至尝试过不依赖jdbc.batchUpdate()而自己做。还是没有运气

    Connection connection = jdbcTemplate.getDataSource().getConnection();
    connection.setAutoCommit(false);
    PreparedStatement preparedStatement = 
    connection.prepareStatement(INSERT_USER_TO_GROUP_SQL);

    preparedStatement.setString(1, "1");
    preparedStatement.setString(2, "2");
    preparedStatement.setString(3, "3");
    preparedStatement.setString(4, "4");
    preparedStatement.addBatch();

    preparedStatement.setString(1, "11");
    preparedStatement.setString(2, "22");
    preparedStatement.setString(3, "33");
    preparedStatement.setString(4, "44");
    preparedStatement.addBatch();

    preparedStatement.executeBatch();
    connection.commit();
此外,我还试图用准备好的语句排除问题,所以我尝试对查询进行硬编码。还是不走运

Connection connection = jdbcTemplate.getDataSource().getConnection();
Statement statement = connection.createStatement();
statement.addBatch("INSERT INTO users (groupId, phoneNumber, accountId, source) VALUES('1', '2', '3', '4')");
statement.addBatch("INSERT INTO users (groupId, phoneNumber, accountId, source) VALUES('11', '22', '33', '44')");
statement.executeBatch();
这是我pom中jdbc的版本

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <version>1.5.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.6.RELEASE</version>
</dependency>

org.springframework.boot
弹簧靴启动器jdbc
1.5.2.1发布
org.springframework
SpringJDBC
4.3.6.1发布

我希望这个参数能加快插入速度,让日志显示正确的批处理insert语句。大多数SO文章显示,人们只是在url中设置了
rewritebatchedstatements=true
,它就起作用了。

对于存在jdbcTemplate连接url问题的其他人,不遵守
rewritebatchedstatements=true
检查
pom.xml中的
mysql连接器java
版本

在写这个问题的时候,我

<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.9</version>
</dependency>

mysql

batchUpdate()--如果JDBC驱动程序不支持批更新,则将退回到单个语句上的单独更新

将其升级到5.1.18版,我得到了正确的批量更新,并在mysql常规日志中进行了验证


还有一个我遇到的bug,它可能会为其他人节省一些时间。在5.1.23版中,当您将db url配置为包含
profileSQL=true
时(我认为大多数情况下都是这样),驱动程序和profileSQL之间会出现冲突。

请阅读本文,特别是关于查询性能的部分。那么请你的问题提供更多信息。同时,请确定您是否已打开自动提交,或者是否正在SQL中的
开始事务
/
提交
块中包装多个
插入
语句。谢谢。我编辑了标题,因为我并不真正关心特定的查询性能,它应该很快,因为它只是一个插入,我不认为这是一个典型的“为什么我的查询速度慢”问题,我更感兴趣的是为什么rewritebatchedstatements=true没有得到尊重,并且没有正确地对插入进行批处理。我添加了表结构和自动提交功能,当前已启用。使用
addBatch()
executeBatch()方法的代码在哪里?重写的性能增益来自于使用批处理执行多行插入,从而减少数据库服务器执行的隐式
COMMIT
操作的数量。在调用
executeBatch()
之前,您调用
addBatch()
的时间是否混乱?是的,我是。我添加了jdbcTemplate.batchUpdate()实现的一个片段,我在第一个示例中使用该方法调用addBatch()和executeBatch()。我还添加了另一个我尝试过的代码片段,在这里我显式调用addBatch()和executeBatch(),而不使用内置的JdbcTemplate方法batchUpdate()
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <version>1.5.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.6.RELEASE</version>
</dependency>
<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.9</version>
</dependency>