brunch

매거진 백엔드

You can make anything
by writing

C.S.Lewis

by 내가 사는 세상 Dec 05. 2023

Django Model - 쿼리 최적화

Django ORM에서 사용되는 성능 최적화 기능들을 알아보자. 이와 관련해서 2가지 기능이 있는데, 이들 모두 관련된 객체를 미리 로딩(Eager Loading <-> Lazy Loading)하여 추가적인 쿼리를 방지한다.


목차 

1. select_related()

2. prefetch_related()




1. select_related()


DB에서 데이터를 가져올 때 연관된 것들도 가져와 lazy loading을 방지하여 N+1문제를 해결


fields를 매개변수로 사용 : 그래서 특정 인스턴스의 필드값을 바로 가져올 수 있는 것임

하나의 쿼리로 관련된 객체들을 가져오기 때문에 쿼리 수 감소

OTO(One-To-One : OneToOneField ), MTO(Many-To-One : ForeignKey)관계에서 주로 사용

작은 데이터셋에서 효과적


single-valued relationships(OTO(One-To-One), MTO(Many-To-One) 관계)에서만 사용가능하다. 이는to avoid the much larger result set that would result from joining across a 'many' relationship 때문이다.


실제 SQL문이 다음과 같이 변화한다.

creating an SQL join 

including the fields of the related object in the SELECT statement




예시

# models.py

from django.db import models


class Author(models.Model):

    name = models.CharField(max_length=100)


class Book(models.Model):

    title = models.CharField(max_length=200)

    author = models.ForeignKey(Author, on_delete=models.CASCADE)




# views.py

from django.shortcuts import render

from .models import Book


def book_list(request):

    books = Book.objects.select_related('author').all()

    return render(request, 'book_list.html', {'books': books})


이렇게 하지 않으면

instance = Book.objects.all()

instance.author

로 2번 실행해야함




2. prefetch_related()


lookups를 매개변수로 사용

prefetch 말 그대로 설정한 값과 관련된 부분을 미리 가져와서 성능 향상

OTO(One-To-One), MTO(Many-To-One), MTO(Many-To-One), MTM(Many-To-Many) 관계에서 사용

대규모 데이터셋에서 효과적


예시

# views.py

from django.shortcuts import render

from .models import Book


def book_list(request):

    books = Book.objects.prefetch_related('author').all()

    return render(request, 'book_list.html', {'books': books})


책들에 대한 쿼리를 실행하는 동안 author(관련된 저자)들도 함께 미리 가져와서 성능을 최적화하는 것이다.




참고자료


공식문서 : https://docs.djangoproject.com/en/5.0/ref/models/querysets/#prefetch-related pdf p.1692, 1694

매거진의 이전글 Django - 기본설정 config
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari