Menu
CoddyTech

쿼리 줄이기

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

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

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

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

ForeignKey 필드의 이름, 즉 loan.book으로 읽는 필드의 이름을 전달하면 됩니다. 그리고 filter() 및 order_by()와 계속 연결해서 사용할 수도 있습니다. 정방향 ForeignKey만 따라가며, 역방향 관계와 다대다 필드에는 Authors 프로젝트에서 다룬 prefetch_related()를 사용합니다. 쿼리 수는 줄어들지만 페이지는 이전과 똑같이 보입니다.

challenge icon

챌린지

중급

홈 페이지와 검색 페이지에는 각각 책의 저자가 표시됩니다. 책이 몇 권이든 쿼리 수가 동일하게 유지되도록 책과 함께 저자도 가져오세요:

  • home 뷰
  • search 뷰

실행을 누르세요. 페이지는 이전과 똑같이 보입니다. 검사에서는 쿼리 수를 셉니다.

직접 해보기

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 플레이그라운드