python - 过滤器中的反向查找和 Django ORM 中的 pks 正向查找哪个更快?

标签 python django django-queryset

我有一个 Django 模型结构,如下所示:

# Pre-defined User model

class A(models.Model):
    pass

class B(models.Model):
    relevant_users = models.ManyToManyField(User)
    related_A = models.ForeignKey(A)

给定一个用户,我想快速生成一个附加到B的所有A的查询集,其中用户位于relevant_users多对多中。我预计会有很多 A,但每个 A 只有一到两个 B,并且仅对 pk 进行索引。

我有两种生成此查询集的方法,并且都有效:

方法一: 通过反向查找过滤 A 对象。

queryset = A.objects.filter(B__relevant_users__exact=user)

方法2: 通过正向查找获取 A pks 的列表,然后在 A 表中查找这些 pks。 (使用了 select_lated,但为了清楚起见,此处省略了)

a_pks = [b.related_A.pk for b in user.b_set.all()]
queryset = A.objects.filter(pk__in=a_pks)

这些是等价的吗?对于大量 A,它们是否具有相同的时间复杂度?

编辑:看起来方法 2 在某些情况下更快:

对于人口稀少的relevant_users(大部分为空白):

答:10,000 m1:0.0014s 平方米:0.0024s

答:100,000 m1:0.0016s 平方米:0.0028s

对于人口稠密的relevant_users(所有 B 都至少有一个用户):

答:10,000 m1:0.040s 平方米:0.019s

答:20,000 m1:0.066s 平方米:0.031秒

最佳答案

方法 2 需要两次往返数据库,因此自然比方法 1 慢近两倍,方法 1 仅需要一次往返。当您只能执行一个查询时,请避免执行两个查询,除非一个查询需要过于复杂的聚合,而有时可以在 python 的客户端更快地执行该聚合。

关于python - 过滤器中的反向查找和 Django ORM 中的 pks 正向查找哪个更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51051581/

相关文章:

python - 夹层部署 Apache2 wsgi 时遇到错误

python - 如何在 django allauth 更改密码 View 返回响应后添加成功消息

python - 如何在 Django 中对日期和时间执行聚合?

python - 如何在 Django 中基于类的分页 View 中迭代当前页面中的对象?

python - Django 按组保留一个元素,然后在此查询集上使用属性

python - 通过脚本运行 Scrapy spider & 配置输出文件的设置

python - python 中的 oauth2

django - 如何更改modelForm选择字段的empty_label?

python - 使用 python django-dashing 从 MySQL 提取数据以显示在仪表板上

python - Django OR 复杂查询