JDBC 커넥션을 생성할 때 rewriteBatchedStatements 옵션을 true 로 하면 MySQL Connector/J 가 addBatch() 함수로 누적된 레코드를 모아 다음과 같은 형태의 구문으로 실행합니다.
INSERT INTO employees VALUES
(10000, 'Brandon', 'Lee'),
(10000, 'Brandon', 'Kim'),
(10000, 'Brandon', 'CHo');
- rewriteBatchedStatements = false 일때 그래프 입니다
- rewriteBatchedStatements = true 일때 그래프 입니다
- 세로축 : 밀리초당 실행된 쿼리수를 의미하므로 높은 값일수록 빠른 성능을 의미합니다.
가로축 : executeBatch() 함수로 실제 쿼리를 실행하기전에 addBatch() 함수의 이해 몇 건의 레코드가 누적 됐는지 나타나는 수치 입니다.
- 1번 그래프는 레코드 건수와 관계없이 거의 비슷한 성능을 보여줍니다.
- 2번 그래프는 addBatch() 함수에 의해 배치로 처리된 레코드 건수에 따라 상당한 성능 차이를 보여줍니다.
- executeBatch() 로 쿼리를 실행하기전에 addBatch() 함수가 32번 실행됐을때가 가장 빠른 성능을 보여주고 있습니다. 그렇다면 32라는 수치는 뭘까요?
- 이 그래프에서 사용된 데이터 평균 레코드 크기는 375바이트 이고 mysql 네트워크 버퍼사이즈는 12KB 입니다.
- 375 * 32 를 하면 12,000 바이트가 되는데 즉 executeUpdate() 를 실행하기 전에 addBatch() 로 누적된 데이터가 12KB 에 접근할때 가장 빠른 성능을 보여줍니다.
- executeBatch() 로 쿼리를 실행하기전에 addBatch() 함수가 32번 실행됐을때가 가장 빠른 성능을 보여주고 있습니다. 그렇다면 32라는 수치는 뭘까요?
정리
정리하자면 어플리케이션에서 INSERT 배치로 처리할때 executeBatch() 함수로 실제 쿼리하기전에 addBatch() 를 몇 번 실행하는냐가 중요합니다. 그래서 다음과같은 방법으로 적정 레코드 수를 구할수있습니다.
1
2
3
mysql 네트워크 버퍼사이즈 = 저희버전은 16kb 입니다
배치 적정 레코드 건수 = (mysql 네트워크 버퍼사이즈 * 1024) / (평균 레코드 크기)
평균 레코드 크기 ? = INSERT INTO coupon (id, type, amount) VALUES (default, 1, 10000) <- 이 쿼리의 길이