我有200K行插入到一個單一的數據庫表中。我試圖在春季使用jdbcTemplate.batchUpdate
,以便每批插入10,000個。但是,這個過程會消耗太多時間(200K行7分鐘)。所以在數據庫方面,我檢查了select count(*) from table_X
插入的行數。我發現行數增加了10K的預期。任何人都可以解釋什麼是理由,還是應該在數據庫端配置的東西?爲什麼彈簧jdbcTemplate batchUpdate逐行插入
PS:我使用Sybase ....
我有200K行插入到一個單一的數據庫表中。我試圖在春季使用jdbcTemplate.batchUpdate
,以便每批插入10,000個。但是,這個過程會消耗太多時間(200K行7分鐘)。所以在數據庫方面,我檢查了select count(*) from table_X
插入的行數。我發現行數增加了10K的預期。任何人都可以解釋什麼是理由,還是應該在數據庫端配置的東西?爲什麼彈簧jdbcTemplate batchUpdate逐行插入
PS:我使用Sybase ....
嘗試連接字符串下面設置 - useServerPrepStmts=false&rewriteBatchedStatements=true
。沒有嘗試,但它從我的書籤。您可以搜索這些行..
Connection c = DriverManager.getConnection("jdbc:<db>://host:<port>/db?useServerPrepStmts=false&rewriteBatchedStatements=true", "username", "password");
它看起來像它不' t工作的sybase :( –
嗯,但仍然檢查該帖子和該帖子中的鏈接 - 它可能會幫助 –
是的謝謝你的建議,我會更新這個職位,當我找到一個解決方案 –
有很多方法可用於網絡。 性能直接取決於你所寫的
沒有看任何人都可以猜到你的代碼,但沒有人能找到確切的解決方案。
方法1
//insert batch example
public void insertBatch(final List<Customer> customers){
String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Customer customer = customers.get(i);
ps.setLong(1, customer.getCustId());
ps.setString(2, customer.getName());
ps.setInt(3, customer.getAge());
}
@Override
public int getBatchSize() {
return customers.size();
}
});
}
參考
https://www.mkyong.com/spring/spring-jdbctemplate-batchupdate-example/
http://docs.spring.io/spring-framework/docs/3.0.0.M4/reference/html/ch12s04.html
方法2.1
//insert batch example
public void insertBatch(final List<Customer> customers){
String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
List<Object[]> parameters = new ArrayList<Object[]>();
for (Customer cust : customers) {
parameters.add(new Object[] {cust.getCustId(),
cust.getName(), cust.getAge()}
);
}
getSimpleJdbcTemplate().batchUpdate(sql, parameters);
}
Alternatively, you can execute the SQL directly.
//insert batch example with SQL
public void insertBatchSQL(final String sql){
getJdbcTemplate().batchUpdate(new String[]{sql});
}
refernce
https://www.mkyong.com/spring/spring-simplejdbctemplate-batchupdate-example/
方法2.2
public class JdbcActorDao implements ActorDao {
private SimpleJdbcTemplate simpleJdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
public int[] batchUpdate(final List<Actor> actors) {
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(actors.toArray());
int[] updateCounts = simpleJdbcTemplate.batchUpdate(
"update t_actor set first_name = :firstName, last_name = :lastName where id = :id",
batch);
return updateCounts;
}
// ... additional methods
}
方法2.3
public class JdbcActorDao implements ActorDao {
private SimpleJdbcTemplate simpleJdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
public int[] batchUpdate(final List<Actor> actors) {
List<Object[]> batch = new ArrayList<Object[]>();
for (Actor actor : actors) {
Object[] values = new Object[] {
actor.getFirstName(),
actor.getLastName(),
actor.getId()};
batch.add(values);
}
int[] updateCounts = simpleJdbcTemplate.batchUpdate(
"update t_actor set first_name = ?, last_name = ? where id = ?",
batch);
return updateCounts;
}
// ... additional methods
}
方法3:JDBC
dbConnection.setAutoCommit(false);//commit trasaction manually
String insertTableSQL = "INSERT INTO DBUSER"
+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES"
+ "(?,?,?,?)";
PreparedStatement = dbConnection.prepareStatement(insertTableSQL);
preparedStatement.setInt(1, 101);
preparedStatement.setString(2, "mkyong101");
preparedStatement.setString(3, "system");
preparedStatement.setTimestamp(4, getCurrentTimeStamp());
preparedStatement.addBatch();
preparedStatement.setInt(1, 102);
preparedStatement.setString(2, "mkyong102");
preparedStatement.setString(3, "system");
preparedStatement.setTimestamp(4, getCurrentTimeStamp());
preparedStatement.addBatch();
preparedStatement.executeBatch();
dbConnection.commit();
refernce
https://www.mkyong.com/jdbc/jdbc-preparedstatement-example-batch-update/
/*Happy Coding*/
感謝您的答覆。我的代碼是方法3使用原生的JDBC準備語句,實際上插入是通過包含10K行的批處理有效地完成的,但是10K行需要25到30秒才能終止,這是不可接受的:( –
我使用的是Sybase 15.5,並且猜測它可能是Sybase的問題,因爲我用PostgreSQL用相同的代碼進行了測試,PostgreSQL在10K行上的時間不到1秒,我曾經向DBA團隊徵求意見,感謝上面的例子。 –
顯示你的代碼,您使用的BatchPreparedStatementSetter?你在你的服務或DAO上使用@Transactional註釋嗎? –
@SheetalMohanSharma而不是使用spring,我切換到本地jdbc api並自己處理transactioin。它現在有效。雖然它仍然很慢.... –
有效我刪除@Transactional註釋可能會導致問題....但我刪除它,以加速insection。 ...它沒有幫助 –