사용중인 h2 database의 insert 방식을 개선하기 위해서 성능을 테스트해 보았습니다.
현재 구성된 간단한 구조는 다음과 같습니다.
- 구성: Java, h2 database(Embedded mode-1.3.169), mybatis, RMI(Remote Method Invocation)
- 시나리오
1) 다른 프로세스로 부터 RMI(Remote Method Invocation)를 통하여 로그를 수신 받는다.
2) 수신된 로그는 곧바로 h2 database에 insert 한다.
3) h2 database를 통하여 모니터링 정보를 표시한다.
위 시나리오 중에서 2)번에 해당하는 insert 부분에 대하여 성능 테스트를 해 보았습니다.
1) 방식 1 - 단일 쿼리
수신된 로그를 곧바로 insert 한다. (로그 1개당 1개의 쿼리 사용)
쿼리 형태: insert into tbLogs ... values ...
처리 속도: 5만개 - 00:00:03.257, 50만개 - 00:00:20.925
2) 방식 2 - 멀티 쿼리 (execute)
수신된 로그를 특정 기간(5초) Queuing 후에 모아서 insert 한다. (5초간 로그당 1개의 쿼리 사용)
쿼리 형태 : insert into tbLogs ... vlaues (..., ..., ...)
conn = dataSource.getConnection();
stat = conn.createStatement();
stat.execute(query);
처리 속도: 5만 처리 - 00:00:01.321, 50만 처리 : 00:00:09.064
* 1번 대비 : 2~3배 향상
3) 방식3 - executeBatch (prepareStatement)
수신된 로그를 특정 기간으로 모아서 insert 한다. 단, prepared statement를 사용한다.
쿼리 유형 : insert into tbLogs ... vlaues (?, ?, ?)
conn = dataSource.getConnection()
pstmt = conn.prepareStatement(query)
pstmt.addBatch();
...
pstmt.executeBatch();
처리 속도: 5만 처리: 00:00:00.676, 50만 처리 : 00:00:02.931
* 1번 대비 : 5~7배 성능 향상
결론:
1) 대량의 로그를 insert 시에는 반드시 모아서 bulk insert 하도록 한다.
2) 동일한 bulk insert를 하더라도 가능한 prepared statement를 사용하여 구성한다.
- From Joshua(2016.09.26)
'Programming > Database' 카테고리의 다른 글
[PostgreSQL] 인덱스 정보 확인하기 (0) | 2018.07.06 |
---|---|
delete 와 truncate의 차이 (0) | 2013.01.25 |
[PostgreSQL] 테이블 Lock 확인하기 (0) | 2013.01.23 |
DB별 Top N 얻어오기 (0) | 2011.11.29 |
[MSSQL] DISTINCT와 GROUP BY의 차이 (4) | 2011.10.21 |
댓글