인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

이호준님의 프로필 이미지

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

페치 조인 2 - 한계

jpa batchsize 관련 문의입니다

작성

·

51

0


=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)


2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)

3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
이해가 잘 되었는 지 확인하고 싶어서 질문 드립니다

팀마다 100개의 맴버가 있고 팀이 400개가 있다고 가정하고 다음 명령을 실행 한다면

String jpql = "select t from Team t";
List<Team> result = em.createQuery(jpql, Team.class)
        .setFirstResult(0)
        .setMaxResults(3)
        .getResultList();
result.forEach(team -> {
    System.out.println("teamname = " + team.getName() + ", team = " + team);
    team.getMembers().forEach(member -> {
        //페치 조인으로 팀과 회원을 함께 조회해서 지연 로딩 발생 안함
        System.out.println("-> username = " + member.getName() + ", member = " + member);
    });
});



1.배치 사이즈를 적용하지 않은 경우
em.createQuery 실행으로 400개의 팀이 영속성 컨텍스트에 로딩된다
스트림에서 팀 내부의 맴버에 접근시
멤버를 영속성 컨텍스트에 로딩 하기위한 쿼리가 날아간다. 이 쿼리는 한 팀당 팀에 소속된 멤버를 로딩한다
따라서 1+400개의 쿼리가 날아간다

2. 배치 사이즈(100)을 적용한 경우
em.createQuery 실행으로 400개의 팀이 영속성 컨텍스트에 로딩된다
스트림에서 팀 내부의 멤버에 접근 하면 해당 팀의 멤버가 로딩되지 않은 것을 확인한다
영속성 컨텍스에 존재하는, 멤버가 로딩되지 않은 팀들의 id를 배치 사이즈 즉 100개 만큼 수집한다.
수집된 팀 ID들을 사용하여 하나의 IN 쿼리를 날려 해당 팀들의 멤버들을 한 번에 로딩한다
이후 다른 팀의 getMembers()가 호출되면, 아직 멤버가 로딩되지 않은 팀들의 ID를 다시 수집하여 IN 쿼리를 날리는 과정을 반복한다
총 1+4 만큼 쿼리가 날아간다

이 시나리오가 정확한지 알고 싶습니다!

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 이호준님

바로 정답을 말씀드리면 좋겠지만, 개발자는 본인이 의심되는 부분을 스스로 확인하고 테스트 해 볼 때 공부한 내용을 진짜 자신의 지식으로 만들 수 있습니다.

확인하고 싶은 시나리오 대로 가상의 데이터를 DB에 저장하고, 실행되는 SQL의 수를 확인해보시겠어요? 그리고 추가로 관련된 결과를 남겨주시면 다른 분들께도 도움을 주실 수 있을거에요 🙂

참고로 .setMaxResults(3) 부분은 제거하셔야 정확한 테스트를 하실 수 있을거에요.

감사합니다.