Menu
CoddyTech

쿼리 줄이기

Coddy Django 여정의 모델과 관리자 섹션에 포함된 레슨. 23개 중 19번째.

홈 페이지는 각 책의 저자를 출력하며, 여기에는 비용이 따릅니다. 한 쿼리로 책을 가져온 다음 {{ book.author.name }}이 책마다 쿼리를 하나 더 실행합니다. 책이 열 권이면 쿼리는 열한 번, 천 권이면 천한 번 실행됩니다. 이는 Django 페이지가 느려지는 흔한 원인인 N+1 문제입니다.

select_related()를 사용하면 이 문제를 해결할 수 있습니다. ORM이 SQL JOIN을 사용해 관련 행을 같은 쿼리에서 가져옵니다. 각 대출의 책 제목을 출력하는 대출 페이지에서는 다음과 같이 요청합니다.

loans = Loan.objects.select_related("book")

loan.book처럼 읽는 ForeignKey 필드의 이름을 전달하면 되며, filter()와 order_by()도 계속 연결해 사용할 수 있습니다. 이 기능은 ForeignKey를 정방향으로만 따라갑니다. 저자의 책이나 다대다 필드에는 Authors 프로젝트에서 사용한 prefetch_related()가 필요합니다. 적용 후에도 페이지는 똑같이 보이지만 쿼리 수는 줄어듭니다.

challenge icon

챌린지

중급

books/views.py에서 home과 search의 QuerySet이 각 책의 저자를 같은 쿼리에서 가져오도록 하세요. 검색 필터는 유지하세요.

‘실행’을 누르세요. 페이지는 이전과 동일하게 보입니다. 검사는 책 10권을 추가하고 페이지당 두 개의 쿼리를 허용합니다.

직접 해보기

from django.shortcuts import get_object_or_404, render

from .models import Book


def home(request):
    books = Book.objects.all()
    return render(request, "books/home.html", {"books": books})


def book_detail(request, pk):
    book = get_object_or_404(Book, pk=pk)
    return render(request, "books/book_detail.html", {"book": book})


def search(request):
    q = request.GET.get("q", "")
    books = Book.objects.filter(title__icontains=q)
    return render(request, "books/search.html", {"q": q, "books": books})
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

모델과 관리자의 모든 레슨

직접 연습해 보세요: Django 플레이그라운드