Django 최적화를 위해 아주 중요한 함수 두개를 설명하겠다.
우리는 queryset을 이용하여 데이터를 불러올 때 db를 몇번 호출하느냐가 중요하다. sql문법에서는 query문 하나로 내가 원하는 데이터를 불러올 수 있지만 django를 통해서 호출한다면 한번 호출 하면 될 문제를 엄청 많은 수의 호출로 만들수 있다.
select_related
select_related()는 내가 원하는 테이블에 정참조된 테이블을 join시켜 한번에 데이터를 불러온다.
select_related를 사용하지 않아도 django에서 데이터를 호출 할 수 있지만 아래와 같은 결과를 초래한다.
queryset = Book.objects.all()
books = []
# QuerySet이 평가(Evaluation)될 때, N + 1 Problems 발생
# 모든 book을 조회하는 SQL 1번 실행
# book 하나당 publisher를 매번 조회하는 SQL N번 실행
for book in queryset:
books.append({
'id': book.id,
'name': book.name,
'publisher': book.publisher.name # book.publisher에 접근, 캐싱되지 않은 데이터이므로 query 발생
}
)
위의 코드를 실행하게되면 매번 publisher의 데이터를 가져오기위해 데이터 베이스에 접근하게된다. 처음 queryset에서 정참조된 데이터를 불러오지 않았기 때문이다. 9000번의 호출과 30초가 걸렸다.
하지만 select_related()를 사용하면
queryset = Book.objects.all().select_related("publisher")
books = []
for book in queryset:
books.append({
'id': book.id,
'name': book.name,
'publisher': book.publisher.name
}
)
2번 호출했다고 보이지만 자세히보면 select 문은 한개이다.
Set이라는 transaction문이 왜 호출된지는 모르겠다.
30초 걸리며 9000번 호출하는 코드와 0.48초 걸리며 1번 호출하는 코드.. 당연히 select_related() 써야한다.
sql문법 join문을 사용하게됨.