[Django] 장고 ORM 쿼리 N+1 해결하기

2024. 1. 29. 22:42·Back/django

쿼리 N+1 문제

  • 쿼리 한번으로 N건의 데이터를 가져왔을때, 원하는 데이터를 얻기위해 N건의 데이터를 가져온 데이터 수만큼 반복해서 2차적으로 쿼리를 수행하는 성능 이슈

해결 방법 : Eager-loading

  • lazy-loading를 피해야 한다.
    • lazy-loading 이란 django에서 ORM을 작성할때, queryset에 담겨있는 데이터를 이용할 때에 SQL문을 호출하는 것
django는 이러한 성능 문제를 해결할 수 있도록 Lazy-loading방식을 피하고 Eager-loading방식으로 바꾸는 두가지 방법을 제공함. select_related() 와 prefetch_related()다. 두 메서드 모두 ORM(객체 관계 매핑)을 사용할 때 성능 최적화를 위해 사용되는 method이다. 두 method의 차이점은 select_related()는 같은 쿼리내에서 관련된 instances를 가져오는 것이고, prefetch_related()는 두번째 쿼리에서 가져온다는 것임.

select_related()

  • 'select_related()'는 ForeignKey나 OneToOneField와 같은 정방향 참조 관계를 가진 모델을 미리 가져와서 쿼리의 JOIN을 통해 데이터베이스에서 한 번에 가져오는 메서드.
  • 이는 N+1 문제를 방지하고, 성능을 향상시킬 수 있다.
  • 주로 정방향 참조를 통해 연결된 객체의 필드를 사용할 때 효과적이며 적은 수의 쿼리로 관련된 객체를 가져올 수 있기 때문에, 단일 객체에 대한 성능 최적화에 유용하다.

prefetch_related()

  • 'prefetch_related()'는 ForeignKey, OneToOneField 뿐만 아니라 ManyToManyField, GenericRelation 등 모든 종류의 관계에 사용할 수 있습니다.
  • 정방향 참조와 달리, 역참조에서 필요한 데이터를 미리 조회하여 쿼리 결과를 가져온다.
  • 이는 별도의 쿼리를 실행하여 필요한 데이터를 가져오므로, 한 번에 여러 관계를 처리할 때 유용하다.
  • 단점으로는 추가적인 쿼리를 실행하므로, 일부 상황에서는 select_related보다 더 많은 쿼리를 발생시킬 수 있다.

  • prefetch_related은 원래의 main query가 실행된 후 별도의 query를 따로 실행하고 select_related은 하나의 query만으로 related objects들을 다 가져옴.
  • ManyToMany, ManyToOne의 관계에서는 prefetch_related를 사용해야 하지만 foreign_key, OneToOne과 같은 single-valued 관계가 있는 곳에서는 최대한 select_related를 사용하여 query수를 줄여주는 것이 좋을 수 있다.

'Back > django' 카테고리의 다른 글

[Django] 일대일관계로 User 모델 확장하기  (0) 2024.01.05
[Django] models.py 정리  (1) 2023.12.27
[Django] Django 프로젝트 시작하기 위한 기본 명령어  (0) 2023.12.14
'Back/django' 카테고리의 다른 글
  • [Django] 일대일관계로 User 모델 확장하기
  • [Django] models.py 정리
  • [Django] Django 프로젝트 시작하기 위한 기본 명령어
6eom9eun
6eom9eun
  • 6eom9eun
    개발 공간
    6eom9eun
  • 전체
    오늘
    어제
    • 전체보기 (33)
      • Front (7)
        • flutter (2)
        • react (5)
      • Back (4)
        • node.js (2)
        • django (4)
      • AI (2)
      • KT Aivle (1)
      • Coding Test (13)
        • 프로그래머스 (5)
        • 백준 (8)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
    • 설정
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    poetry
    PYTHON
    OpenAI
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
6eom9eun
[Django] 장고 ORM 쿼리 N+1 해결하기
상단으로

티스토리툴바