Как улучшить производительность запросов n + 1 - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть следующее:

#models:py    
class Author(models.Model):
    name = models.CharField(max_length=20)

class Book(models.Model):
    author = ForeignKey(Author)
    title = models.CharField(max_length=20)

class Comment(models.Model):
    book = ForeignKey(book)
    title = models.CharField(max_length=20)

#views.py
class AuthorBookComment(ListView):
    model = Author
    paginate_by = 5
    template = “template.html”

#template.html  
{% for author in object_list %}
    <h2>{{ author.name }}</h2>
    {% for book in author.book_set.all %}
        <h3>{{book.title}}</h3>
        {% for comment in book.comment_set.all %}
            {{comment.title}}<br/>
        {% endfor %}
    {% endfor %}
{% endfor %}
<<pagination code>>

Идея состоит в том, чтобы показать всех авторов, их книги и комментарии (если таковые существуют).

Проблемы: 1. Снижение производительности при увеличении объемов данных (количество запросов sql = n + 1). 2. Разбивка на авторский набор по сравнению с автором + книга + набор комментариев.

Вопрос: Как можно улучшить / оптимизировать вышесказанное?

Я пробовал разные версии select_related () и prefetch_related (). Результаты ниже, но все еще недостаточно производительные + большие наборы данных возвращаются. Есть ли способ лучше?

Запросы, TimeMs: Queryset
230, 106: Author.objects.all ()
229, 105: Author.objects.all (). Prefetch_related (book_set '). All ()
179, 88: Author.objects.all (). Prefetch_related ('book_set__comment_set'). All ()

1 Ответ

0 голосов
/ 04 апреля 2019

В этих ситуациях вы всегда должны загружать данные, используя select_related () или prefetch_related () .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...