Lazy Loading & Eager Loading

박효상·2022년 12월 20일
0

Django

목록 보기
2/2
post-thumbnail

Lazy Loading 이란?

  • Django에서 Queryset으로 ORM 명령어를 통한 쿼리 요청시 어떤 데이터를 필요로 하는지 모르기에 일일이 쿼리를 보내는 방식
  • Lazy Loading 방식으로 인해 ORM으로 명령어를 실행할 때마다 Database에 접근해 데이터를 조작하는 것이 아니라 모든 명령 처리가 끝나고 실제 데이터를 접근해야 할 시점이 왔을 때 Database에 쿼리를 실행
  • 예시
    • books.writer.name 으로 데이터 접근시에 쿼리 발생
    books = books.objects.all()   # SELECT books.id, books.title FROM books      
    for book in books:
        print(book.writer.name)    # SELECT writers.id, writers.name FROM writers WHERE id = n

Eager Loading

  • Lazy Loading과 반대로 하나의 Queryset을 가져올 때 사전에 쓸 데이터를 포함한 쿼리를 날려 관련 objects들을 불러오기에 비효율적으로 늘어나는 쿼리를 방지하는 방식
  • 불러온 데이터들은 local data cache에 보관된다
  • Django에선 prefetch_related() 또는 select_related()를 통해 Lazy Loading이 아닌 Eager Loading으로 처리 가능
    • Queryset 내 result_cache에 저장되어 캐싱되기에 중복 호출 방지로 성능 최적화
    • selected_related : SQL Join과 같은 쿼리 역할 수행하며, single-valued(1:1 또는 1:N에서 N) 정참조 관계에서만 사용 가능
    • prefetch_related : SQL WHERE-in과 같은 쿼리 역할 수행하며, 모든 관계에서 사용 가능. selected_related 와는 다르게 부모 객체를 조회하는 하나의 쿼리와 Join&WHERE-In을 통해 자식 객체를 조회하는 쿼리가 발생하여 하나 더 많은 쿼리가 발생
  • 예시
    • 실제로 접근할 데이터(books)를 포함한 쿼리를 날려, 쿼리 최소화
    writers = writers.objects.prefetch_related('books').get(id=n)  
  • 결론
    • selected_related()가 prefetch_related()보다 적은 쿼리 실행으로 성능은 뛰어나지만, 1:1, 1:N에서 N으로 정참조로만 사용 가능하기에 상황에 따라 유동적인 적용이 필요
profile
집념의 백엔드 개발자

0개의 댓글