카테고리 없음

지연로딩과 즉시로딩 개념, 스스로 짚고 가기

podori 2023. 3. 25. 17:51

이제 지연로딩(fetchType = LAZY)과 즉시로딩(fetchType = EAGER) 개념에 대해 알아보도록 하겠습니다.

지연로딩과 즉시로딩은 join을 할 때, 객체를 가져오는 방식이라고 할 수 있습니다.

 

지연로딩과 즉시로딩은 연관 Entity 영속화를 언제 하느냐에 차이를 두고 있습니다. (영속화의 시점에 따라서 지연로딩과 즉시로딩 구분)

LAZY와 EAGER의 각각 개념에 대해 명시하자면 다음과 같습니다.

  • 즉시로딩(EAGER): 최초 테이블 데이터를 모두 불러오고, 바로 연관관계가 있는 엔티티까지 싹 다 조회합니다.
  • 지연로딩(LAZY): 최초 테이블 데이터를 모두 불러오고, 필요한 시점에만 연관관계가 있는 엔티티를 조회합니다.
    • 지연로딩에서 처음 불려질 때에는 실제 객체가 아닌, 프록시(proxy)객체로 가져옵니다. 프록시 객체를 영속화합니다.
    • 필요한 시점에 조회할 때에만 실제 객체를 가져옵니다. 이를 '프록시 객체를 초기화한다'고 합니다. 

지연로딩이 왜 생겼는지 의문이 들 수도 있습니다. 처음부터 필요한 데이터를 다 깔아둔 다음, 입맛에 맞게 골라 쓰면 되지 않냐고 할 수 있습니다. 그러나 이는 단순한 엔티티 관계에서는 별 문제가 없어보일 수 있지만, 복잡한 관계가 설정된다면 많은 쿼리가 나가게 될 것이고 이는 성능 저하로 직결될 수도 있습니다. 

그래서 지연로딩은 효과적으로 필요한 연관관계만 조회하도록 하는 것입니다. 

 

지연로딩과 즉시로딩 개념을 공부하게 되면, N+1 문제를 흔히 접할 수 있습니다. 

지연로딩을 적용하여 N+1문제를 해결할 수 있는 경우는 단순 조회의 경우에만 해결할 수 있습니다. 연관관계가 걸린 엔티티이더라도, 조회할 때에는 프록시 객체로 넘겨받기 때문에 N+1문제가 발생하지 않기 때문입니다.

 

조회를 넘어서 연관관계가 걸린 Entity 프록시 객체의 데이터값을 건드린다면, 바로 N+1문제가 발생합니다. 

지연로딩 또한 N+1문제를 피하기 힘들고, 즉시로딩보다 발생시점을 늦춰주기만 할 뿐입니다.

이 때의 문제상황을 해결하기 위해서 fetch join 방식이 나오게 됩니다.