[SPRING] 왜 스프링 jdbcTemplate batchUpdate 행마다 삽입
SPRING왜 스프링 jdbcTemplate batchUpdate 행마다 삽입
하나의 단일 데이터베이스 테이블에 200K 행을 삽입해야합니다. 배치 당 10,000 삽입을 수행하기 위해 봄에 jdbcTemplate.batchUpdate를 사용하려고했습니다. 그러나이 프로세스는 너무 많은 시간을 소비합니다 (200K 행의 경우 7 분). 따라서 데이터베이스 측에서는 table_X에서 select count (*)에 의해 삽입 된 행 수를 확인합니다. 10K의 예상보다 약간 증가한 행 수가 발견되었습니다. 누구든지 이유를 설명 할 수 있습니까, 아니면 데이터베이스 측에서 구성해야하는 것이 있습니까?
추신 : 나는 sybase를 사용하고 있습니다 ....
해결법
-
==============================
1.웹에는 여러 가지 접근 방식이 있습니다. 성능은
웹에는 여러 가지 접근 방식이 있습니다. 성능은
코드를 보지 않으면 누구나 추측 할 수 있지만 정확한 솔루션을 찾을 수있는 사람은 없습니다.
접근법 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); }
또는 SQL을 직접 실행할 수 있습니다.
//insert batch example with SQL public void insertBatchSQL(final String sql){ getJdbcTemplate().batchUpdate(new String[]{sql}); }
참고
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();
참고
https://www.mkyong.com/jdbc/jdbc-preparedstatement-example-batch-update/
/*Happy Coding*/
-
==============================
2.연결 문자열-useServerPrepStmts = false & rewriteBatchedStatements = true에 대해 아래 설정을 시도하십시오. 내 북마크에서 시도하지는 않았습니다. 이 줄을 검색 할 수 있습니다.
연결 문자열-useServerPrepStmts = false & rewriteBatchedStatements = true에 대해 아래 설정을 시도하십시오. 내 북마크에서 시도하지는 않았습니다. 이 줄을 검색 할 수 있습니다.
Connection c = DriverManager.getConnection("jdbc:<db>://host:<port>/db?useServerPrepStmts=false&rewriteBatchedStatements=true", "username", "password");
from https://stackoverflow.com/questions/39576061/why-spring-jdbctemplate-batchupdate-insert-row-by-row by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring AOP : pointcut에서 최종 클래스와 열거를 피하십시오. (0) | 2019.08.13 |
---|---|
[SPRING] ManyToMany 단방향 관계에 대한 Spring Data JPA 사양 (0) | 2019.08.13 |
[SPRING] Gradle의 Spring Boot에서 Tomcat 종속성 제외 (0) | 2019.08.13 |
[SPRING] JPA 동시성 문제 "배치 릴리스시 여전히 JDBC 문이 포함되어 있습니다" (0) | 2019.08.13 |
[SPRING] 간단한 Spring JMS 클라이언트 확인 작동 (0) | 2019.08.13 |