我有一个看起来像这样的Django模型结构:
# Pre-defined User model
class A(models.Model):
pass
class B(models.Model):
relevant_users = models.ManyToManyField(User)
related_A = models.ForeignKey(A)
给定一个User
,我想快速生成一个查询集,其中包含用户在relevant_users
多对多情况下与B相连的所有A。我希望有很多A,但是每个A只有一个或两个B,并且仅对pk进行索引。
我有两种方法来生成此查询集,并且都可以工作:
方法1: 使用反向查找过滤A对象。
queryset = A.objects.filter(B__relevant_users__exact=user)
方法2: 使用正向查找获取A pk的列表,然后在A表中找到这些pk。 (使用的是select_related,为清楚起见,在此省略)
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
(大多数为空白):
A:10,000 m1:0.0014s 平方米:0.0024秒
A:100,000 m1:0.0016秒 平方米:0.0028秒
对于人口稠密的relevant_users
(所有B都有至少一个用户):
A:10,000 m1:0.040秒 平方米:0.019秒
A:20,000 m1:0.066秒 平方米:0.031秒
答案 0 :(得分:1)
方法2与数据库进行两次往返,因此自然比方法1(仅进行一次往返)慢近两倍。当您只能执行一个查询时,请避免进行两个查询,除非一个查询需要过于复杂的聚合,有时有时可以在python的客户端上更快地进行聚合。