N+1 문제라고도 하는 ORM을 사용할시 정말로 주의해야하는 문제점이다. 이가 문제가 해결이 안되는건 아니지만 반복되는 쿼리를 통해서 더많은 DB 조회를 하게되고 최종적으로 성능을 떨어트리는 쿼리를 만드는 문제이다. (특징만 말했으니 빨리 설명을 보자.)

N+1 문제란

연관 관계가 설정된 엔티티를 조회할 경우에 조회된 데이터 갯수 (n) 만큼 연관관계의 조회 쿼리가 추가로 발생하여 데이터를 읽어오는 현상

즉시 로딩인 경우

Lazy Loading 이던 Eager Loading

Django ORM으로 보기

books = Book.objects.order_by('title')
for book in books:
	print(book.title, 'by', book.author.name)

이 흐름의 순서를 기억해보자.

  1. 우리는 Book이라는 QuerySet을 만들었다. 이는 Lazy Load를 하게된다. (데이터가 필요할때 DB에 데이터를 조언하는것을 합니다
  2. Book QuerySet을 반복합니다. 반복하나당 하나의 쿼리문을 가져온다.
  3. Book QuerySet의 book.author.name은 외래키이기 때문에 기존의 Book QuerySet 에 데이터가 없다. 그러기에 장고는 다른 쿼리를 불러오게 된다.

즉 쿼리를 하나만 실행하는게 아니라 2개를 실행하게 되는 문제점이다.

해결법

Django

외래키와 연결된 데이터도 가져올 수 있는 쿼리를 보낸다. Django에서는 select_related() , prefetch_related()가 존재한다.


N+1 문제