2019.09.24 django select_related, prefetch_related

문제의 제기

  • 기본적으로 장고의 ORM은 불필요한 쿼리문을 많이 요청한다는 이야기가 많았다. 실제로 확인을 해보니 불필요한 중복 쿼리문이 너무 많이 사용되고 있었다.
  • 디버그 툴바를 활용하면 불필요한 쿼리문의 요청들을 확인할 수 있다.

기본적으로 ORM에서는 하나의 모델을 바탕으로 Foreignkey가 묶인 다른 자료들도 불러서 사용할 수 있다.

  • 문제는 여기서 발생하게 된다. 하나의 모델을 불러오고 또 그 관련된 Foreignkey가 연관된 자료들을 불러오려고 하면 DB에 접근을 2번이나 해야 한다.
  • 그렇다면 하나의 모델을 불러올 때 미리 foreignkey로 연결된 자료까지 불러 올 수 있으면 어떨까? 그렇게 되면 DB에 접근을 한번만 해도 된다!

select_related와 prefetch_related란?

  • select_related와 prefetch_related는 하나의 Queryset을 가져올 때, 미리 related objects들까지 다 불러와주는 함수이다.
  • 비록 query를 복잡하게 만들지만, 불러온 데이터는 모두 cache에 남아있게 되므로 DB에 다시 접근해야 하는 이슈가 줄어들 수 있다.
  • 2가지는 모두 DB에 접근하는 수를 줄여주어, performance를 줄여주지만 그 방식에는 차이가 있다.

select_related와 prefetch_related의 차이

  • 와 위의 글을 읽고 머리를 딱 쳤다.
  • select_related와 prefetch_related 모두 필요한 데이터들을 모두 한번에 가지고 올 수 있게 도와준다.
  • select_related는 foreign-key 혹은 one-to-one과 같은 1:1 관계에서 사용이 가능하다.
  • 그에 반해 prefetch_related의 경우 many to many, foreign-key 등 가리지 않고 사용이 가능하다.
  • 하지만 실제로 해당 내용을 한번에 모두 가지고 오기 위해 호출해야 하는 횟수가 다르다.
  • 결론부터 말하자면 prefetch_related가 더 많은 쿼리문(순차적으로 불러옴)을 실행해야 되는 반면에 select_related는 한번의 쿼리문으로 모든 것을 가지고 온다.

결론

  • select_related와 prefetch_related를 적절하게 사용하면 제일 좋다 :)

확인 방법

  • debug toolbar의 SQL문을 참고해보면 된다!

참고

'Django' 카테고리의 다른 글

django celery 적용하기  (0) 2020.03.17
Django migration 되돌리기, 재실행 방법  (3) 2020.01.29
Django queryset filter와 exists()  (0) 2019.12.28
Django Lock에 관해서  (0) 2019.12.28
Django model(default, blank, null)  (0) 2019.12.28

+ Recent posts