jdbcバッチ更新が非常に遅い理由について、インターネット+ stackoverflow全体で読んできました。適切な修正が接続文字列にrewriteBatchedStatements = true
を設定するように見えます。しかし、私はそれが私のために働くように感じることはできません。私はspringbootと春-JDBC私も?rewriteBatchedStatements=true
ことを確認するために、ブレークポイントを設定しているmysql jdbc rewriteBatchedStatements = trueの後でも照会をバッチしない
spring.datasource.url=jdbc:mysql://RDS_URL.us-west-2.rds.amazonaws.com/DATABASE?rewriteBatchedStatements=true
アイブ氏は私のapplication.propertiesでrewriteBatchedStatements = true
を設定を使用しています
は私がgeneral_logいる
コードに反映されていますtrueに設定し、ログを見ると、挿入が適切にバッチ処理されていないことがわかります
これは私のSQL文字列の外観です
012ログにprivate static String INSERT_USER_TO_GROUP_SQL = "INSERT INTO users (groupId, phoneNumber, accountId, source) VALUES(?, ?, ?, ?)";
行はすべて、この
45 Query INSERT INTO users (groupId, phoneNumber, accountId, source) VALUES('49', '99999999999', '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()を呼び出します。
for (int i = 0; i < batchSize; i++) {
pss.setValues(ps, i);
if (ipss != null && ipss.isBatchExhausted(i)) {
break;
}
ps.addBatch();
}
return ps.executeBatch();
私は
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`phoneNumber` varchar(20) DEFAULT NULL,
`groupId` varchar(11) DEFAULT NULL,
`source` varchar(30) DEFAULT NULL,
`accountId` varchar(50) DEFAULT NULL,
`deleted` int(1) DEFAULT '0',
`timestamp` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `phoneNumber` (`phoneNumber`,`groupId`,`accountId`)
) ENGINE=InnoDB AUTO_INCREMENT=21677 DEFAULT CHARSET=latin1;
に挿入しています表には、私も(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();
これは私のポンポンでの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>
イム挿入をスピードアップするために、このパラメータを期待して、ログが正しくバッチ処理insert文を表示するためです。ほとんどのSOの記事は、URLにrewritebatchedstatements = true
と設定するだけの人々を示しています。私のバッチ書き込みが1に起こったので、私は
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
を持っていたこの質問を書いている時点で、あなたのpom.xml
であなたのmysql-connector-java
バージョンを確認rewriteBatchedStatements = true
を尊重ないjdbcTemplate接続URLの問題を持つ他の人のために
この記事、特にクエリのパフォーマンスに関するセクションをお読みください。 http://meta.stackoverflow.com/a/271056/質問を編集して詳細をお知らせください。その間、自動コミットを有効にしているか、複数の 'INSERT'文をSQLの' BEGIN TRANSACTION'/'COMMIT'ブロックにラップしているかどうかを調べてください。 –
ありがとうございます。私は本当に特定のクエリのパフォーマンスについて心配していないので、タイトルを編集した、それはちょうど挿入のようにすばやくする必要があり、私はこれは典型的な "なぜ私のクエリが遅い"質問だとは思わない rewritebatchedstatements = trueは尊重されておらず、正しくインサートをバッチ処理しません。 Iveはテーブル構造と自動コミットを追加し、現在は – qHack
になっています。 'addBatch()'と 'executeBatch()'メソッドを使用するコードはどこですか?書き換えによるパフォーマンスの向上は、バッチを使用して複数行の挿入を行うことにより、データベースサーバによって実行される暗黙的な 'COMMIT'操作の数を削減することにあります。 'executeBatch()'を呼び出す前に、 'addBatch()'を何度も呼び出すのですか? https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#addBatch(java.lang.String) –