백엔드 개발을 하다보면 쿼리 최적화에 신경을 안 쓸 수가 없다.
특정 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
'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 |