Django ORM (select_related & prefetch_related)

hs·2021년 12월 8일
0

지난 글에 이어 프로젝트를하며 앞으로 개발을 하면서 가장 크게 작용할 부분이라 생각했던 부분이다.

ORM을 쓰는 이유
데이터베이스의 접근을 줄이는 방법
Django를 좀 더 활용하는 법

드디어 그 세번째 Django를 좀 더 활용하는 법(ft.데이터베이스 접근을 줄이는 방법)에 대해 정리한다.

이 두 가지를 알기 위해선 좀 더 django에 대해 생각해보아야한다.

N+1 problem

N+1 Problem이란 쿼리 1번으로 N건을 가져왔을때, 관련 컬럼을 얻기 위해 쿼리를 N번 추가 수행하는 문제이다.
Django ORM은 Lazy-Loading방식이므로 ORM에서 명령을 사용할 때마다 DB에서 데이터를 가져오는 것이 아닌 모든 처리가 끝나고 호출 시정에서 쿼리를 실행하는 것이다.
이러한 Lazy-Loading의 문제를 해결할 방법이 Eager-Loading이다. Eager-Loaging은 사전에 쓸 데이터를 포함하여 쿼리를 날려준다.

여기서 Eager-Loading이 바로 select_relatedprefetch_related이다.

쿼리셋과 캐싱
각각의 쿼리셋에는 데이터베이스 액세스를 최소화하기 위한 캐시가 포함되어 있다. 처음 생성된 쿼리셋에서는 캐시가 비어있기 때문에 Query가 발생한다. 그 후 동일한 쿼리셋이 사용되어 질 경우 추가적인 Query가 발생하지 않고 캐시에서 꺼내 사용하게 된다.

select_related는 foreign-key, OneToOne처럼 single-valued relationship에서 사용이 가능하며 INNER JOIN 하여 데이터를 가져온다.

prefetch_related는 foreign-key, OneToOne뿐만이 아닌 ManyToMany, ManyToOne과 같은 모든 관계에서 사용이 가능하다. prefetch_related는 데이터를 가져와서 MEMORY JOIN하는 형식으로 저장해 둔다.

profile
무엇이든 끝까지 보람차게

0개의 댓글