使用django queryset时如何提高性能?

时间:2018-02-19 05:03:24

标签: sql django orm

我正在尝试制作新闻Feed。每次调用页面时,服务器都必须发送多个项目。一个项目包含帖子,喜欢的数量,评论数量,评论儿童数量,评论数据,评论儿童数据等。

我的问题是,每次调用我的页面时,都需要加载超过5个secondes。我已经实现了一个缓存系统。但它仍然很慢。

       posts = Posts.objects.filter(page="feed").order_by('-likes')[:'10'].cache()
    posts = PostsSerializer(post,many=True)

    hasPosted = Posts.objects.filter(page="feed",author="me").cache()
    hasPosted = PostsSerializer(hasPosted,many=True)


    for post in post.data:

        commentsNum = Comments.objects.filter(parent=posts["id"]).cache(ops=['count'])
        post["comments"] = len(commentsNum)
        comments = Comments.objects.filter(parent=posts["id"]).order_by('-likes')[:'10'].cache()
        liked = Likes.objects.filter(post_id=posts["id"],author="me").cache()

        comments = CommentsSerializer(comments,many=True)
        commentsObj[posts["id"]] = {}
        for comment in comments.data:

            children = CommentChildren.objects.filter(parent=comment["id"]).order_by('date')[:'10'].cache()
            numChildren = CommentChildren.objects.filter(parent=comment["id"]).cache(ops=['count'])
            posts["comments"] = posts["comments"] + len(numChildren)
            children = CommentChildrenSerializer(children,many=True)
            liked = Likes.objects.filter(post_id=comment["id"],author="me").cache()



            for child in children.data:

                if child["parent"] == comment["id"]:
                    liked = Liked.objects.filter(post_id=child["id"],author="me").cache()

我试图找到一种简单的方法来更快地获取所有这些数据,而不会造成不必要的数据库命中。如果可能的话,我需要将加载时间从5秒减少到不到1秒。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

  1. 在注释字段中添加子项数作为整数,每次添加或删除注释时都会更新。这样,您就不必查询该值。你可以使用信号来做到这一点。

  2. 配置文件模型中添加 ArrayField (如果您使用的是postgres)或类似内容,该模型存储喜欢的所有主键< / strong>帖子。您可以这样做,而不是查询Likes模型:

    profile = Profile.objects.get(name ='me')

    likes =如果profile.liked_posts中的comment_pk为假,则为真

  3. 对CommentChildren使用 select_related ,而不是对其进行额外查询。

  4. 实现这3个项目将摆脱在“comments.data中的注释” forloop中执行的所有数据库查询,这可能占用了大部分处理时间。

    如果您有兴趣,请查看django-debug-toolbar,这样您就可以查看每个页面上正在执行的查询。