백엔드 개발을 하다보면 쿼리 최적화에 신경을 안 쓸 수가 없다. 

 

특정 DB 테이블을 조회할 때, 해당 테이블과 연관된 테이블의 정보를 한 번에 조회하여 데이터 뭉치를 가져오는 것

 

매 번 조회를 하는 것보다 당연히 성능이 좋기 때문에, 쿼리를 어떤 식으로 날릴지 잘 설계해야한다.

 

스프링에서는 이럴 때 fetch join을 사용하거나 즉시 로딩을 사용할 수 있었는데, 즉시 로딩은 한 번 설정하면

 

선택의 여지 없이 매 번 데이터 뭉치를 가져와야 하는 단점 때문에 거의 사용하지 않고 대부분 fetch join으로 해결했다.

 

Django에서는 이러한 DB 접근 방식으로 select_related와 prefetch_related를 사용한다.

 

select_related

조회할 객체가 역참조 single object(one-to-one or many-to-one)이거나, 정참조 FK일 때 사용한다.

위와 같은 DB 테이블이 있을 때, TpQuickTestAnswerSet 테이블을 조회하면서 연관된 TpQuickTestQuestion 테이블까지 조회하려면 select_related를 사용하면 된다.

 

>>> answer_set = TpQuickTestAnswerSet.objects.select_related('tp_quick_test_question').get(id=1)

>>> question_id = answer_set.tp_quick_test_question.pk

 

prefetch_related

조회할 객체가 정참조 multiple objects(many-to-many or one-to-many)이거나, 역참조 FK일 때 사용한다.

위와 같은 DB 테이블이 있을 때, TpQuickTestQuestion 테이블을 조회하면서 연관된 TpQuickTestAnswerSet 테이블까지 조회하려면 prefetch_related를 사용하면 된다.

 

lowercase 모델이름_set : default 역참조 메서드 이름. ForeignKey 필드에 related_name을 정하면 default이름을 대신하여 사용할 수 있다.

 

>>> question = TpQuickTestQuestion.objects.filter(id=1).prefetch_related('tp_quick_test_answer_set_set')

 

 

정참조: FK를 가진 테이블에서 가지지 않는 테이블을 참조

역참조: FK를 가지지 않은 테이블에서 가진 테이블을 참조

 

References

https://velog.io/@rosewwross/Django-selectrelated-%EC%99%80-prefetchedrelated%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%B0%B8%EC%A1%B0

'Django' 카테고리의 다른 글

Django __str__  (0) 2021.08.30
Django 쿼리문 F() 사용하기  (0) 2021.08.04
Django ORM query set 중복 제거  (0) 2021.07.26
Django query/url parameter  (0) 2021.07.13
Django 세팅하기  (0) 2021.07.11

+ Recent posts