해결된 질문
작성
·
194
0
안녕하세요~ 강의 잘 들었습니다!
다름이 아니라 ItemReader를 구현하는 과정에서 궁금한 게 생겨 질문드립니다.
상황 1)
chunkSize가 2000이면서 ItemReader에서는 1개의 row만 DB로부터 읽어 1개의 객체씩 반환하는 ItemReader
상황 2)
chunkSize가 1이면서 ItemReader에서는 2000개의 row를 DB로부터 읽어 2000개의 객체가 포함된 1개의 List 객체를 반환하는 ItemReader
두 상황 다 DB커넥션은 1번만 맺고 쿼리를 실행할 것 같긴 한데
DB 입장에서는 둘 중 어느 상황을 더 빨리 처리할지,
또 코드 상으로는 둘 중 어느 방식으로 구현하는 게 유지보수나 외 측면에서 좋을지,
또 어느 방식으로 ItemReader를 구현해야 성능 상 더 좋을지 궁금합니다!
답변 2
0
일단 2의 상황을 보자면 chunkSize가 1 이면 데이터 1개의 읽기, 처리, 쓰기 트랜잭션이 완료되고 새로운 트랜잭션이 시작됩니다.
즉 커넥션을 반환하고 다시 커넥션을 가지고 와야 하는 비용이 듭니다.
단순하게 생각해도 이 정도이지만 1개의 데이터를 메모리로부터 가지고 오는 비용을 2000 번 해야 하는 상황이 발생하기 때문에 성능 이슈가 심각해 집니다.
디비로부터 데이터를 가지고 온다는 것은 파일, 즉 디스크로부터 가지고 오는 것이기 때문에 한번 가지고 올 때 청크 단위로 가지고 오는 것이 훨씬 더 성능에 좋습니다.
마치 자바에서 데이터를 파일로 부터 읽어올때 버퍼에 담아서 오는 것이 더 성능에 유리한 것과 동일한 개념입니다.
0
지나가는 학생입니다.
상황 1의 경우 스프링 배치에서 제공하는 ItemReader에는 없을 것 같군요.
굳이 구현한다면 ItemReader 인터페이스를 직접 구현해서 사용할텐데, 해당 구현 내용에는 select * from table limit 1 offset 0...2000
이렇게 증가하면서 조회한다고 가정하겠습니다.
상황 1과 상황 2의 성능을 비교한다면,차라리 상황 1이 더 더 빠르다고 생각되네요.
어차피 상황 1과 2 둘다 커넥션 풀에 있는 커넥션을 사용할거라 커넥션 생성 비용은 동일할텐고요.
다만, 상황 2에서는 chunk size 단위로 커밋이 이뤄지기 때문에 커밋(네트워크 통신) 2000번이 발생하겠네요.
상황 1에서는 write 커밋은 1번할테니 둘의 커밋 차이는 2000배가 되겠네요.
도움이 되셨기를~