TIL) select_related & prefetch_related

Jiwon Lee·2022년 10월 3일
0

TIL

목록 보기
18/19

selected_related, prefetch_related 모두 장고에서 기본으로 제공하는 기능이며, ORM 최적화를 위한 것이다. selected_related와 prefetch_related 모두 DB에 접근하는 횟수를 줄이고, 빠르게 효율적으로 데이터를 조회할 수 있게 만들어주며, 한번 불러온 데이터들을 캐싱하기 때문에, 매번 쿼리마다 DB에 접근하지 않고 캐싱된 것에서 불러오게 되므로 성능이 개선되는 장점이 있다. 또한 두 가지 모두 Eager Loading을 하기 때문에 ORM의 N+1의 문제도 해결할 수 있다.

selected_related란?
SQL Query문의 JOIN을 사용해서 foreign key('one-to-one' or 'many-to-one')를 사용해서 정참조할 때에 사용한다. 쿼리셋을 가져올 때에 미리 related objects까지 불러오는 함수이다.

비록 쿼리는 복잡해지겠지만, 한번에 불러온 데이터들은 DB서버가 종료되기 전 까지 Cache에 남게 되어서 매 쿼리마다 DB에 접근하지 않아도 되는 장점이 있다.

  • 괄호 안에 따옴표로 필드명이나 클래스명을 소문자로 입력하면 related_name 옵션이 적용된다.
  • filter와 selected_related의 순서는 상관이 없다고 한다.

prefetch_related란?
selected_related와 같이 data를 Cache에 저장하며, 모든 relationship에서 사용이 가능하다.

  • 객체가 정참조 multiple objects('many-to-many' or 'one-to-many')이거나, 또는 역참조 foreign key인 경우
  • 각각의 관계 별로 DB 쿼리를 수행하고, 파이썬 단계에서 JOIN을 수행한다.
  • prefetch_related를 쓰는 경우, 반복문 안에서는 .first()보다 .all()[0]을 활용하는게 좋다.

selected_related와 prefetch_related중 어느 것이 사용 가능한 지는 모델 객체의 .__dir__으로 확인이 가능하다.

selected_related는 하나의 쿼리로 related objects를 불러오지만, prefetch_related는 메인 쿼리가 실행이 된 후에 별도의 쿼리가 실행이 된다. 따라서 한번 이상의 쿼리가 진행되기 때문에, 가급적 selected_related를 사용하는 것이 리소스의 소모를 줄일 수가 있다고 한다.

prefetch_related로 역참조를 할 시에 lookup에 '_set'을 사용한다.

0개의 댓글