首页 > 解决方案 > 如何提高查询性能n+1

问题描述

我有以下内容:

#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:查询集 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()

标签: django

解决方案


在这些情况下,您应该始终使用select_related()prefetch_related() 预先加载数据。


推荐阅读