복붙노트

[SPRING] 왜 스프링 jdbcTemplate batchUpdate 행마다 삽입

SPRING

왜 스프링 jdbcTemplate batchUpdate 행마다 삽입

하나의 단일 데이터베이스 테이블에 200K 행을 삽입해야합니다. 배치 당 10,000 삽입을 수행하기 위해 봄에 jdbcTemplate.batchUpdate를 사용하려고했습니다. 그러나이 프로세스는 너무 많은 시간을 소비합니다 (200K 행의 경우 7 분). 따라서 데이터베이스 측에서는 table_X에서 select count (*)에 의해 삽입 된 행 수를 확인합니다. 10K의 예상보다 약간 증가한 행 수가 발견되었습니다. 누구든지 이유를 설명 할 수 있습니까, 아니면 데이터베이스 측에서 구성해야하는 것이 있습니까?

추신 : 나는 sybase를 사용하고 있습니다 ....

해결법

  1. ==============================

    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. ==============================

    2.연결 문자열-useServerPrepStmts = false & rewriteBatchedStatements = true에 대해 아래 설정을 시도하십시오. 내 북마크에서 시도하지는 않았습니다. 이 줄을 검색 할 수 있습니다.

    연결 문자열-useServerPrepStmts = false & rewriteBatchedStatements = true에 대해 아래 설정을 시도하십시오. 내 북마크에서 시도하지는 않았습니다. 이 줄을 검색 할 수 있습니다.

    Connection c = DriverManager.getConnection("jdbc:<db>://host:<port>/db?useServerPrepStmts=false&rewriteBatchedStatements=true", "username", "password");
    
  3. from https://stackoverflow.com/questions/39576061/why-spring-jdbctemplate-batchupdate-insert-row-by-row by cc-by-sa and MIT license