joeylee.log
로그인
joeylee.log
로그인
Django ORM (QuerySet) 최적화
Joey Lee
·
2020년 12월 2일
팔로우
3
3
Django
목록 보기
22/23
본 자료는 "
Django ORM(QuerySet) 구조와 원리 그리고 최적화 전략
"이라는 PyCon Korea 2020에서 김성렬님이 강의하신 내용을 요약 정리한 것입니다.
1. 목차
2. 쿼리셋을 통해 알아보는 ORM의 특징
1) Lazy Loading : 지연 호출
정말 필요한 시점에 SQL를 호출한다.
정말 필요해야만 SQL을 호출한다.
정말 필요한 만큼만 호출한다.
=> 두 번 호출하지 않도록 주의해야 한다. 예제 3번 참고.
2) Caching
QuerySet 캐싱을 재사용해서 3번 케이스를 예방함
3) Eager Loading 즉시 로딩 : N+1 Problem
쿼리셋은 Lazy Loading을 함. 하지만 SQL로 한 번에 여러 개의 데이터를 가져오고 싶을 때가 있는데 이게 Eager Loading이라고 하고, 이를 지원하기 위해 select_related, prefetch_related 메소드를 제공하고 있음.
Lazy Loading이기 때문에 정작 필요한 for문에서 계속 쿼리를 날려서 아래와 같이 N+1번 동일한 쿼리를 날릴 수 있음
3. 쿼리셋 상세
1) 쿼리셋 구성요소
쿼리셋은 1개의 쿼리와 추가 쿼리로 구성된다.
쿼리셋을 호출하고 나면, 그 자료는 캐시에 저장되고 이후에는 캐시에서 불러와서 사용한다. 만약 캐시에 데이터가 없다면 다시 쿼리를 날려서 데이터를 가져온다.
prefetch_related가 추가 쿼리에 해당한다. select_related는 추가 쿼리가 아님
2) select_related()와 prefetch_related()
select_related는 원래 쿼리에 조인을 통해서 데이터를 즉시 로딩하는 방식
prefetch_related는 추가 쿼리를 수행해서 데이터를 즉시 로딩하는 방식
역참조 모델의 경우 select_related 옵션을 줄 수가 없음. 아래 예제에서는 상품의 경우는 select_related를 할 수가 없음. 하지만 그 반대는 가능함. order_owner는 prefetch_related는 가능함. 이건 장고의 제약 사항임
prefetch_related에 추가적인 조건절을 걸고 싶다면 prefetch 함수를 이용하면 됨. (select_related는 뒤에 그냥 filter를 걸면 됨)
3) 연습문제
4) SQL 퍼포먼스를 커버하는 Testcase [CaptureQueriesContext 활용]
4. 실수하기 쉬운 쿼리셋의 특성들
1) prefetch_related는 완전 별개다.
filter는 1개의 쿼리에 대해 이뤄진다. 따라서 추가적인 쿼리인 prefetch_related는 filter의 적용을 받지 않는다.
아래와 같이 하면 불필요한 데이터를 더 검색하게 만드는 비효율적인 쿼리가 되어버림
2) 쿼리셋 작성 순서
Model -> annotate -> select_related -> filter -> prefetch_related
3) 재사용하지 못 하는 쿼리셋
4) RawQuerySet 사용하기
5) 서브쿼리 발생조건 : QuerySet in QuerySet
속도 이슈 때문에 서브쿼리는 가급적 지양해야 함. 근데, 어떤 경우에 서브쿼리가 발생할까?
서브쿼리가 되지 않도록 1개 쿼리가 다 실행되고 그 다음 쿼리가 될 수 있도록 해결해야 함.
Joey Lee
안녕하세요!
팔로우
이전 포스트
Django-dotenv 통한 settings.py 설정
다음 포스트
Django model 학습 키워드
0개의 댓글
댓글 작성