Back/Java

[Java] Preparestatement AddBatch를 사용하여 대용량 데이터 INSERT 처리

Awesome-SH 2020. 8. 3. 14:35

 

연구과제 중 160억건에 달하는 데이터를 기간내에 INSERT 해야하는 이슈가 있었다.

매번 PrepareStatement 를 열고 닫고 하는 시간에서 속도가 떨어지는 것을 확인하게 되었다.

어떻게 하면 Insert를 더 빠르게 할 수 있을까? 생각하다가

Preparestatement에 addbatch() 클래스를 이용하기로 결정했다.

 

동작방법은

쿼리를 즉시 실행하지 않고

메모리에 쿼리문을 올려 놓고 실행 명령을 기다리다가

명령이 떨어지면 DB에 한번에 쿼리를 날리게 되는 것이다.

 

아래는 사용예제 코드를 올려 놓았다.

많은 데이터를 빠르게 INSERT하고 싶을 경우 이 방법을 사용해보면 좋다.

 

실제 사용했을 당시

삼중 반복문안에 INSERT 로직이 담겨져 있었다.

 

Connection 객체설정 부분에

추가적으로 AutoCommit을 false로 설정해준다.

conn.setAutoCommit(false);

 

반복문 안에서는 addBatch와 몇건이 되었을때 execute 할것인지만 설정해주면된다.

// 쿼리는 String SQL에 담겨있다고 가정한다.

// PrepareStatment가 닫혀있으면 생성해 준다
if(pst.isClosed()) {
	pst = conn.prepareStatement(SQL);
}

pst.setInt(1, ....);
..
..
..


// PrepareStatement Batch에 담아준다.
pst.addBatch();

// 쿼리문을 클리어 한다.
pst.clearParameters();

// index가 50000 단위마다 execute로 쿼리를 날린다.
if( (index % 5000) == 0 ) {
	try {
		pst.executeBatch();
		pst.clearBatch();
		conn.commit();
	} catch (Exception e) {
		System.out.println(e);
	}
}

 

반복문이 끝나고 난뒤 PrepareStatement 객체를 닫아주면

INSERT속도가 체감상 확 빨라진것을 느낄 수 있다.

 

조건설정 시 너무많은 쿼리를 메모리상에 가지고 있으면

Memory Leak 이 발생 할 수 있으니 적당한 크기로 설정해주면 된다.