📌 페치 조인 - 한계
- 페치 조인 대상에는 별칭을 줄 수 없다. (JPA 동작 방식과 관련 O)
- EX) as m where m. ~~ … 불가능
- 페치 조인 은 연관된 엔티티를 한 번의 쿼리로 함께 로딩하기 위한 기능임 !! 페치조인을 사용할 때 특정 엔티티나 컬렉션을 즉시 로딩하게 됨.
- 별칭을 사용하면 명시적으로 어떤 엔티티나 컬렉션을 페치할 것인지 명확하지 않게 됨
- 페치 조인은 주로 데이터 조회를 목적으로 사용됨. 별칭을 사용하게 되면 JPA가 해당 별칭을 가진 엔티티를 정확하게 식별하고 관리하기 어려움. JPA는 엔티티를 로딩할 때 내부적으로 엔티티 매핑 정보를 사용하여 자동으로 처리하기 때문에, 별칭이 있으면 이러한 과정이 복잡해질 수 있음
- 하이버네이트는 가능, 가급적 사용X
- 특정 조건에 맞는 데이터를 가져오고자 할 때는 별도의 쿼리를 작성하여 데이터를 가져오는 것 맞음
- 둘 이상의 컬렉션은 페치 조인 할 수 없다.
- 카테시안 곱 문제,
- 데이터 불일치 가능성 등
- 컬렉션을 페치 조인하면 페이징 API(setFirstResult, setMaxResults)를 사용할 수 없다.
String query = "select t From Team t join fetch t.members m";
- 컬렉션을 페치 조인하는 경우, 여러 테이블의 데이터를 조인하여 한 번에 로드하게 되는데, 이 과정에서 데이터베이스에서 반환되는 결과는 조인된 데이터의 전체 행 수가 됨.
- 이때 페이징 API를 사용하면, 실제 로드된 데이터가 아닌 조인된 데이터 행 수 기준으로 페이징이 이루어짐. 따라서, 데이터베이스에서 올바르게 페이징이 적용되지 않으며, 이는 예상치 못한 결과를 초래할 수 있음.
- 일대일, 다대일 같은 단일 값 연관필드는 페치조인해도 페이징 가능
String query = "select m From Member m join fetch m.team t";
>> 위 SQL 문에서 member랑 team을 뒤집음. 다대일이 되므로
- 하이버네이트는 경고 로그를 남기고 메모리에서 페이징(매우 위험)
- @BatchSize(size = 100)
- 주로 지연 로딩(Lazy Loading) 과 함께 사용되어, 연관된 엔티티나 컬렉션의 데이터를 한 번에 가져오는 개수를 조절함
- 특정 엔티티 타입 또는 컬렉션 필드에 적용할 수 있으며, 설정된 크기(batch size)만큼의 엔티티를 한 번에 로드함
- 기본적으로 지연 로딩은 하나의 연관된 엔티티나 컬렉션의 데이터를 필요할 때마다 개별 쿼리로 로드>> 다수의 데이터베이스 쿼리 발생(성능 저하O)
- =⇒ @BatchSize를 사용하면 이러한 문제를 완화 !!
- 기본적으로 지연 로딩은 하나의 연관된 엔티티나 컬렉션의 데이터를 필요할 때마다 개별 쿼리로 로드>> 다수의 데이터베이스 쿼리 발생(성능 저하O)
- 연관된 엔티티들을 SQL 한 번으로 조회 - 성능 최적화
- 엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선함
- @OneToMany(fetch = FetchType.LAZY) // 글로벌 로딩 전략
- 실무에서 글로벌 로딩 전략은 모두 지연 로딩
- 최적화가 필요한 곳은 페치 조인 적용 (N+1문제와 같은..)
=⇒ 이러면 대부분의 성능 문제는 잡힘
- 모든 것을 페치 조인으로 해결할 수 는 없음
- 페치 조인은 객체 그래프를 유지할 때 사용하면 효과적
- 여러 테이블을 조인해서 엔티티가 가진 모양이 아닌 전혀 다른 결과를 내야 하면, 페치 조인 보다는 일반 조인을 사용하고 필요한 데이터들만 조회해서 DTO로 반환하는 것이 효과적
반응형