Java mysql jdbc即使在重写BatchedStatements=true之后也不会批处理查询
我一直在互联网上阅读关于为什么jdbc批量更新如此缓慢的文章。看起来正确的修复方法是在连接字符串中设置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
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>