본문 바로가기

Dev/Spring Boot

API 최적화1 - N + 1 문제, Lazy 메커니즘, 패치조인

728x90

N + 1 문제

Ex) 주문내역 엔티티는 회원 엔티티와 상품정보 엔티티 두개를 가지고 있다고 해보자 이 때, 주문내역 엔티티를 조회하면 어떻게 될까? 만약 3개의 주문내역이 있다고 생각해보자 그렇다면 결과는 3개가 나와야한다.

즉, 조회된 엔티티의 개수(N)만큼 추가적인 쿼리가 발생하는 문제를 뜻한다.

  1. 주문내역 엔티티를 구하기 위한 질의를 던진다.
  2. 주문내역에 회원 엔티티를 구하기 위한 질의를 던진다.
  3. 상품정보 엔티티를 구하기 위한 질의를 던진다.

지금 주문 내역 엔티티를 구하기 위해 쿼리가 2개가 더 날아갔다. 이것이 1 + N 문제이다. 하나의 쿼리면 될 것을 몇개나 더 날린다. 그리고 주문내역이 3개 있으므로 이 엔티티는 무려 7개의 쿼리를 날려야한다. 단순히 생각해도 네트워크 통신이 많다.

왜 이럴까?

Lazy Loading의 메커니즘

지연로딩은 위 처럼 다른 엔티티를 가지고 있는 엔티티를 사용하기 위해 쿼리를 날렸을 때 먼저 결과를 만들어두고 프록시로 가상의 데이터를 넣어둔 다음 이후 엔티티를 사용할 때 로딩한다. 그러므로 이후 사용하게 될 때 계속 루프당 1번씩 테이블을 조회하게 되는 것이다.

Fatch- join

이를 해결하기 위한 첫번째 방법 패치조인이다.

select o from order o 
join fatch o.user u
join fatch o.info, order class 

이러면 여러개의 쿼리가 나갔던 것에 비해 단 하나의 쿼리가 날아간다. 패치조인은 JPA의 아주 중요한 문제이고 많은 최적화 문제가 발생하기 때문에 꼭 알고가야한다.

그러나 이 패치조인도 단점이 있는데 바로 이렇게 하면 오더의 유저, 인포 모든 속성컬럼이 출력된다는 것이다. 이것의 대한 것은 다음 포스팅에서!