【问题标题】:How expensive are `count` calls for Django querysets?Django 查询集的“count”调用有多贵?
【发布时间】:2016-06-07 16:22:14
【问题描述】:

我有一个我必须呈现的“帖子”列表。对于每个帖子,我必须做三个过滤查询集,将它们组合在一起,然后计算对象的数量。这合理吗?哪些因素可能会导致速度变慢?

这大概是我的代码:

def viewable_posts(request, post):

    private_posts = post.replies.filter(permissions=Post.PRIVATE, author_profile=request.user.user_profile).order_by('-modified_date')
    community_posts = post.replies.filter(permissions=Post.COMMUNITY, author_profile__in=request.user.user_profile.following.all()).order_by('-modified_date')
    public_posts = post.replies.filter(permissions=Post.PUBLIC).order_by('-modified_date')

    mixed_posts = private_posts | community_posts | public_posts

    return mixed_posts

def viewable_posts_count(request, post):

    return viewable_posts(request, post).count()

【问题讨论】:

  • 请发布一些代码:模型,查询。 “慢”是索引、到数据库的往返、需要从数据库到 Web 服务器的数据量等问题。非常具体
  • 呃,我粗略地添加了视图代码。我认为该模型非常明显。

标签: django database django-models django-orm


【解决方案1】:

我能看到的最大因素是您对每个帖子都有过滤操作。如果可能,您应该在 ONE 查询中查询与每个帖子关联的结果。从count 开始,这是从查询中获取结果数量的最有效方式,因此可能不是问题。

【讨论】:

  • 如果我在执行查询之前 OR 查询集,这算作一个查询吗?
【解决方案2】:

试试下面的代码:

def viewable_posts(request, post):

    private_posts = post.replies.filter(permissions=Post.PRIVATE, author_profile=request.user.user_profile).values_list('id',flat=True)
    community_posts = post.replies.filter(permissions=Post.COMMUNITY, author_profile__in=request.user.user_profile.following.values_list('id',flat=True)
    public_posts = post.replies.filter(permissions=Post.PUBLIC).values_list('id',flat=True)

   Lposts_id = private_posts
   Lposts_id.extend(community_posts)
   Lposts_id.extend(public_posts)

   viewable_posts  = post.filter(id__in=Lposts_id).order_by('-modified_date')
   viewable_posts_count  = post.filter(id__in=Lposts_id).count()

   return viewable_posts,viewable_posts_count

它应该改进以下几点:

  1. order_by 一次,而不是三次
  2. count 方法在只有索引字段的查询上运行
  3. django 使用更快的“值”过滤器进行计数和过滤。
  4. 取决于您的数据库,db 自己的缓存可能会为 viewable_posts 选择最后查询的帖子,并将其用于 viewable_posts_count

确实,如果您可以将前三个过滤查询合并为一个,您也将节省时间。

【讨论】:

    猜你喜欢
    • 2014-04-05
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 2021-11-14
    • 1970-01-01
    相关资源
    最近更新 更多