Django 查询集的 count 调用有多昂贵?
How expensive are `count` calls for Django querysets?
我有一个 "posts" 列表,我必须渲染。对于每个 post,我必须执行三个过滤器查询集,或将它们组合在一起,然后计算对象的数量。这合理吗?哪些因素可能会导致速度变慢?
这大概是我的代码:
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()
我能看到的最大因素是您对每个 post 都有过滤操作。如果可能,您应该在一个查询中查询与每个 post 关联的结果。从 count
开始,这是从查询中获取结果数量的最有效方式,因此这可能不是问题。
试试下面的代码:
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
它应该改进以下内容:
- order_by一次,而不是三次
- count 方法在只有索引字段的查询上运行
- django 使用 "values" 更快的过滤器,用于计数和过滤。
- 取决于您的数据库,数据库自己的缓存可能会选择 viewable_posts 的最后查询帖子,并将其用于 viewable_posts_count
确实,如果您可以将前三个筛选查询压缩为一个,您也可以节省时间。
我有一个 "posts" 列表,我必须渲染。对于每个 post,我必须执行三个过滤器查询集,或将它们组合在一起,然后计算对象的数量。这合理吗?哪些因素可能会导致速度变慢?
这大概是我的代码:
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()
我能看到的最大因素是您对每个 post 都有过滤操作。如果可能,您应该在一个查询中查询与每个 post 关联的结果。从 count
开始,这是从查询中获取结果数量的最有效方式,因此这可能不是问题。
试试下面的代码:
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
它应该改进以下内容:
- order_by一次,而不是三次
- count 方法在只有索引字段的查询上运行
- django 使用 "values" 更快的过滤器,用于计数和过滤。
- 取决于您的数据库,数据库自己的缓存可能会选择 viewable_posts 的最后查询帖子,并将其用于 viewable_posts_count
确实,如果您可以将前三个筛选查询压缩为一个,您也可以节省时间。