我正在尝试制作新闻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秒。
有什么建议吗?
答案 0 :(得分:0)
在注释字段中添加子项数作为整数,每次添加或删除注释时都会更新。这样,您就不必查询该值。你可以使用信号来做到这一点。
在配置文件模型中添加 ArrayField (如果您使用的是postgres)或类似内容,该模型存储喜欢的所有主键< / strong>帖子。您可以这样做,而不是查询Likes模型:
profile = Profile.objects.get(name ='me')
likes =如果profile.liked_posts中的comment_pk为假,则为真
对CommentChildren使用 select_related ,而不是对其进行额外查询。
实现这3个项目将摆脱在“comments.data中的注释” forloop中执行的所有数据库查询,这可能占用了大部分处理时间。
如果您有兴趣,请查看django-debug-toolbar,这样您就可以查看每个页面上正在执行的查询。