TIL) N + 1의 문제

Jiwon Lee·2022년 10월 4일
0

TIL

목록 보기
19/19

쿼리셋은 기본적으로 Lazy Lodaing 방식을 선택한다.
하지만, SQL로 한꺼번에 많은 데이터를 가져오고 싶은 때가 있을 것이다.
이러한 방식을 ORM에서 Eager Loading(즉시 로딩)이라고 부른다.
쿼리셋에서는 Eager Loading을 지원하기 위해 selected_related와 prefetch_related라는 메소드를 지원한다.

N + 1의 문제

ORM을 잘 이해하지 못할 경우에 N+1이라는 문제가 생긴다.
그렇다면, N+1이란 어떤 것인가를 예제를 통해서 알아보자.

현재, ERD의 상황은 user와 userinfo라는 테이블이 1:1 관계에 있다.

drinks = Drink.objects.all()

	for drink in drinks:
    	drink.nutrition

첫 줄에서 모든 음료의 정보를 가져온다. 그 후에, 1:1관계에 있는 (해당 음료에 대한)영양 정보를 가져온다고 생각을 해보자.
이 부분에서 N+1의 문제가 발생하게 되는 것이다.

앞의 예제를 보면, drinks라는 쿼리셋에는 모든 drink의 정보들이 담겨있다. 그러나, 영양정보에 대한 내용은 들어가있지 않게 되는 것이다. 때문에 drink는 쿼리셋에서 영양정보를 찾기 위해 SQL에서 다시 호출을 하게 된다.

만약, 스타벅스의 음료의 개수가 100개라고 친다면, 첫 줄에서 모든 음료의 정보를 가져올 때에 이미 한 번의 쿼리의 요청이 생기고, for 루프를 돌면서 음료의 영양정보를 찾기 위해 100번의 쿼리가 더 요청이 될 것이다.

때문에, 100개의 음료에 대한 정보에서 해당 음료에 맞는 영양 정보를 찾기 위한 위의 예제에서 +1이 추가로 생성되는 것이기 때문에, 첫 줄. 즉, Lazy Loading로 인해 발생하는 대표적인 문제인 N+1의 문제가 발생하게 되는 것이다.


  • 그렇다면, N+1에 대한 해결책은?
    즉시 로딩, Eager Loading이라는 방법을 채택해 사용하는 것이 일반적이다.
    이것은 다음에 다뤄보도록 하겠다.

0개의 댓글