SPRING&BOOT/JPA

JPA 지연 로딩(Lazy Loading)

jki09871 2024. 8. 27. 11:36
JPA 지연 로딩(Lazy Loading)은 데이터베이스에서 필요한 시점까지 관련 엔티티를 로드하지 않는 전략이다. 즉, 연관된 엔티티를 처음부터 전부 가져오는 것이 아니라, 실제로 해당 엔티티에 접근할 때 데이터를 가져오는 방식이다. 이는 성능 최적화와 메모리 효율성을 높이기 위해 사용된다.

1. 기본 개념

JPA에서 엔티티는 서로 연관 관계를 가질 수 있다. 예를 들어, 회원과 주문이라는 두 엔티티가 있다고 가정하면, 한 회원이 여러 개의 주문을 가질 수 있다. 이 경우, 회원을 조회할 때 관련된 주문 데이터까지 모두 가져오는 것은 비효율적일 수 있다. 지연 로딩은 이런 상황에서 회원 엔티티만 먼저 로드하고, 주문 데이터는 실제로 필요할 때 로드하는 방식이다.

2. 지연 로딩 설정

지연 로딩은 JPA에서 기본적으로 사용되며, @OneToMany, @ManyToOne, @ManyToMany 등의 관계에서 FetchType.LAZY로 설정할 수 있다. 예를 들어, 아래와 같이 설정할 수 있다

@Entity
public class Member {

    @OneToMany(mappedBy = "member", fetch = FetchType.LAZY)
    private List<Order> orders;

    // ...
}

이렇게 하면 Member 엔티티를 조회할 때 orders 리스트는 실제로 접근할 때까지 데이터베이스에서 조회되지 않는다.

3. 장점과 단점

지연 로딩의 장점은 필요한 데이터만 조회하기 때문에 성능 최적화가 가능하다는 점이다. 특히, 연관된 데이터가 많을 때 초기 로딩 시간을 줄일 수 있다. 또한, 메모리 사용량을 줄일 수 있어 시스템의 안정성을 높인다.

하지만 단점도 존재한다. 첫째로, 엔티티에 실제로 접근할 때 추가적인 쿼리가 발생하기 때문에 N+1 문제를 야기할 수 있다. 이는 하나의 쿼리로 여러 엔티티를 조회할 때 발생하는 문제로, 추가 쿼리가 여러 번 발생해 성능에 악영향을 줄 수 있다. 이를 해결하기 위해 페치 조인(Fetch Join)이나 배치 사이즈(Batch Size)를 설정해 최적화할 수 있다.

5. 즉시 로딩과 비교

지연 로딩과 반대되는 개념은 즉시 로딩(Eager Loading)이다. 즉시 로딩은 연관된 엔티티를 함께 로딩하는 방식으로, FetchType.EAGER로 설정할 수 있다. 이 방식은 초기 조회 시점에 모든 연관 데이터를 가져오기 때문에 코드가 간단해지고, 추가 쿼리 발생을 피할 수 있지만, 불필요한 데이터를 조회해 성능이 저하될 수 있다.

결론

지연 로딩은 JPA에서 성능 최적화를 위한 중요한 전략 중 하나이다. 그러나 N+1 문제와 같은 단점을 이해하고, 상황에 맞게 페치 조인이나 배치 사이즈 등의 기법을 활용해 최적화하는 것이 중요하다. 시스템의 요구사항에 따라 지연 로딩과 즉시 로딩을 적절히 조합해 사용해야 한다.