[MySQL] Batch 및 Load 비교.
- 빅데이터 및 DB/MySQL
- 2018. 8. 20.
MySQL에서 대용량의 데이터 처리를 하기 위해서 주로 쓰이는 두개의 방식인 Batch와 Load 방식에 대한 장단점을 비교하기로 한다. 어느 것이 무조건 좋다 나쁘다를 할 수 없기 때문에 어떤 상황에서 이 방식을 써야 할지 등을 알려보고자 한다.
참고로, 필자가 다니는 회사는 전국민 상대로 서비스를 하고 있으며, 하루에도 몇십만명 이상이 사이트를 방문하기에 당연히 몇백만 이상의 로그가 쌓이고 있다. 데이터 분석을 한 결과(몇천만건 ~ 억단위)를 DB에 매일 배치 형태로 밀어 넣고 있는데 몇백에서 몇기가 단위의 데이터를 DB에 밀어 넣을 때는 늘 상 load(부하)를 잘 관리해야만 할 것이다.
Batch 방식
일단, 많이들 알고 있는 Batch 방식은 Insert를 Add 시킨 후, 한번에 커밋(commit) 하는 방식이다. 이 방식의 장점은 데이터를 핸들링 하기 편하다는 장점이 있다. 보통 데이터를 DB에 로드를 한다는 것은 꽤나 큰 부하이며, 부하가 가지 않는 선 내에서 적절하게 DB에 밀어 넣을 수 있는 장점이 있는데 서비스를 하는 DB에 무리가 간다면 load보다 Batch를 하는 방법이 좋을 것이다.
소스예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | // prepared로 처리 Connection conn = null; PreparedStatement pstmt = null; int rc = 0; String sql = "조회쿼리"; try { conn = getConnection(); pstmt = conn.prepareStatement(query); conn.setAutoCommit(false); for(DicWrdClsVO vo : list) { pstmt.setString(1, vo.getTitle); pstmt.setString(2, vo.getWrdCls()); pstmt.setString(3, vo.getSynm()); pstmt.setString(4, vo.getRegUser()); pstmt.addBatch(); rc++; } pstmt.executeBatch(); conn.setAutoCommit(true); pstmt.clearBatch(); } catch (Exception e) { LOGGER.error("loadDic : " + e.getMessage()); rc = -1; } finally { if (pstmt != null) { pstmt.close(); } if (conn != null) { conn.close(); } } | cs |
Batch를 할 때는, iBatis 혹은 MyBatis같은 프레임워크를 사용하는 것보다 이렇게 Java Sample 소스처럼 코딩한 것을 넣는 것이 훨씬 편하고 빠르다. 예전에 iBatis로 배치 작업을 한 적이 있었지만, 속도면에서 차이가 심했었음.
대용량일 경우, 위 방식에서 for문을 넣은 후, 10만건마다 setAutoCommit(true)등을 넣어주는 방식으로 처리를 해야 부하에 대한 핸들링이 원활할 것이다.
Load 명령어
MySQL에는 LOAD DATA라는 명령어를 지원하고 있는데 csv를 DB에 전송하는 것이다. 이 명령어를 자바로 코딩하여 DB에 직접 밀어넣을 경우, 첫번째 방식인 Batch 작업보다 월등히 빠른 속도를 느낄 수 있을 것이다. 다만 이렇게 할 경우, 대용량의 csv를 밀어 넣을 때, 부하에 대한 컨트롤이 힘든데 이럴 경우 csv를 잘게 쪼개서 넣으면 DB부하를 최소화 할 수 있다.
소스예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Connection conn = null; PreparedStatement pstmt = null; String filename = trinityVO.getServicePath() + "/" + fileNm; String sql = "LOAD DATA LOCAL INFILE \"" + filename + "\" INTO TABLE " + tableNm + " FIELDS TERMINATED BY \',\'" + fields; try { logger.info("load ... begin"); conn = getDBConnection(); pstmt = conn.prepareStatement(sql); conn.setAutoCommit(false); pstmt.executeUpdate(); conn.setAutoCommit(true); pstmt.close(); conn.close(); logger.info("load...end"); } catch (Exception e) { e.printStackTrace(); return false; } | cs |
'빅데이터 및 DB > MySQL' 카테고리의 다른 글
[MySQL] date_format 설정 (날짜 포맷 변경) (0) | 2022.04.24 |
---|---|
[MySQL] group_concat 사용법 모음 (문자열 구분자 묶음) (0) | 2022.04.22 |
[MySQL] ROWNUM(번호) 및 페이징(Paging) 처리 (0) | 2018.08.14 |
[MariaDB] UTF-8 캐릭터(Character) 설정 변경 방법 (2) | 2018.08.08 |
MySQL, MariaDB의 DB, 계정, 권한 생성 및 설정 (0) | 2018.07.31 |