Django 进行 1000 次重复查询

Posted

技术标签:

【中文标题】Django 进行 1000 次重复查询【英文标题】:Django Making 1000 Duplicate Queries 【发布时间】:2016-10-12 16:52:43 【问题描述】:

型号:

class Comment(MPTTModel):

    submitter = models.ForeignKey(User, blank=True, null=True)
    post = models.ForeignKey(Post, related_name="post_comments")
    parent = TreeForeignKey('self', blank=True, null=True, related_name="children")
    text = models.CharField("Text", max_length=1000)
    rank = models.FloatField(default=0.0)
    pub_date = models.DateTimeField(auto_now_add=True)

遍历节点具有相同的效果(>1000 个查询)。

【问题讨论】:

使用工具栏,可以显示包含的回溯吗?我想你可以点击一下sql的边上什么的 【参考方案1】:

我对 MPTT 模型也有类似的问题。已通过select_related 解决 (也适用于父母的外键)。 因此,根据您的需要,正确的查询集可能如下所示:

Comment.objects.select_related('post', 'submitter', 'parent', 'parent__submitter', 'parent__post')

另外,如果您的循环中也需要评论的子项,可以这样优化:

queryset.prefetch_related('children')

甚至是这样:

queryset.prefetch_related(
    Prefetch(
        'children', 
        queryset=Comment.objects.select_related('post', 'etc.'),
        to_attr='children_with_posts'
    )
)

...根据树的深度,您可以使用它:

queryset.select_related('parent', 'parent__parent', 'parent__parent__parent') 
# you got the idea:)

【讨论】:

【参考方案2】:

重复查询的发生是因为当您引用相关对象时,迭代中的所有对象都会命中数据库。

尝试在您的视图方法中使用select_related。

可能使用 django prefetch related 或 select related 可以解决该问题,但如果不起作用,抱歉您需要原始查询。

您是否读过有关优化 Django 查询的文章?这是一个解释很多事情的简单教程:https://docs.djangoproject.com/en/3.1/topics/db/optimization/

【讨论】:

以上是关于Django 进行 1000 次重复查询的主要内容,如果未能解决你的问题,请参考以下文章

使用参数列表进行 django 查询[重复]

Django-使用 ManyToManyField 查询嵌套模型中的重复查询

Django:没有重复的随机查询

基于比较日期的Django查询集[重复]

Django查询集获得精确的多对多查询[重复]

将 Django 过滤器转换为 RAW SQL 查询 [重复]