Django制作1000个重复查询

时间:2016-06-12 01:33:46

标签: sql django postgresql mptt

型号:

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次查询)。

2 个答案:

答案 0 :(得分:3)

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

尝试在视图方法中使用select_related

可能使用django预取相关或选择相关将解决该问题,但如果不起作用,抱歉您将需要原始查询。

你读过有关优化Django查询的内容吗?这是一个简单的教程,可以解释很多内容:http://bookofstranger.com/optimizing-django-orm-queries-for-best-performance/

答案 1 :(得分:3)

我与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:)

编辑:拼写错误