이번 포스팅에서는 JPQL을 사용할때, 성능최적화를 위해 사용되는 페치조인(fetch join)에 대해서 알아보려고합니다.
먼저, 페치조인은 어떤 성능문제가 발생할때 사용되는 것일까요??
바로 JPA fetch전략인 지연로딩(Lazy Loading)과 즉시로딩(Eager Loading)에 의해 N+1문제가 발생할때, 주로 사용하게 됩니다. 그럼 N+1문제가 발생하는 예제코드를 보도록 하겠습니다.
예제코드(N+1문제가 발생하는 코드)
@Entity
public class Member{
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
// getter,setter 생략..
}
@Entity
public class Team extends BaseEntity{
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
// getter,setter 생략...
}
Member와 Team은 페치타입이 지연로딩으로 설정이 되어있고, Member와 Team 모두 persist한뒤 EntityManager를 깨끗하게 초기화 시켜두었습니다. 이렇게 한 이유는 1차캐시를 완벽하게 없애기 위해서입니다.
이제부터는 아래 서로다른 2개의 코드에서 N+1문제가 언제 발생하는지 알아보도록 하겠습니다.
[N+1이 발생하지 않는경우]
![]() |
![]() |
- .getResultList()를 하면서 지연로딩이므로 Member테이블에서만 데이터를 조회한다.
- Member데이터를 1차캐시에 저장한다.
- 반복문을 돌면서 member.getUsername()을 가져오지만, 1차캐시에 Member정보가 저장되어 있어서 추가적인 쿼리가 발생하지 않는다.
[N+1이 발생하는 경우]
![]() |
![]() |
- .getResultList()를 하면서 지연로딩이므로 Member테이블에서만 데이터를 조회한다.
- Member데이터를 1차캐시에 저장한다.
- 반복문을 돌면서 member.getTeam.getName을 가져올때, team정보는 1차캐시에 없기때문에 프록시로 만들어진 team데이터를 조회하기위해 select쿼리를 실행한다.
- 회원1, 회원2는 팀이름이 korea1로 동일하기때문에 회원1의 팀이름인 korea1이 1차캐시에 등록되게 되면 회원2의 팀이름을 조회할때, 1차캐시에 등록되어있는 정보를 사용하면 되므로 select쿼리가 나가지 않는다.
- 1번째, 2번째 회원정보가 System.out.println()으로 출력되면 마지막 3번째 회원정보를 출력하려고하는데, 이때 다시 select쿼리가 나가게된다. 그 이유는 회원1,2의 팀은 korea1이지만, 회원3의 팀은 korea2이다. korea2의 팀정보는 1차캐시에 등록되어 있지 않기때문에 select쿼리가 실행되게 된다.
이런 경우처럼 모든 회원의 팀이 모두 다를경우!!!
N+1문제가 발생하여 성능상의 이슈가 나타날 수 있습니다.
예제코드(fetch조인을 통해 N+1문제 해결)
참고로 JPA에서 사용하는 fetch조인은 SQL조인방식이 아닙니다. 단순 성능최적화를 위한 기능입니다.
![]() |
![]() |
- 기존 쿼리에서 join fetch m.team을 추가하여 페치조인을 실행한다.
- 페치조인을 실행하면 즉시로딩처럼 연관된 테이블의 정보를 한번에 가져온다.
- Member와 Team의 모든 데이터가 1차캐시에 저장되어 있기때문에 추가적인 select쿼리가 나가지 않게되어 N+1문제를 해결하게 된다.
이렇게 페치조인을 사용하게 되면, N+1문제로인한 성능문제를 해결할 수 있게됩니다.
'JPA' 카테고리의 다른 글
[JPA] 컬렉션 조회 최적화 (0) | 2022.02.12 |
---|