如果我想用几种不同的方式计算数据库中的人数,那么将初始People.objects.all()
分配给变量(下面的版本a(会比每次查询更有效吗。
实际上,版本A是否会导致对数据库的一次命中,而版B会导致两次命中?
版本A:
people_var = People.objects.all()
last_name_filter = people_var.filter(last_name='Doe').count()
first_name_filter = people_var.filter(first_name='John').count()
版本B:
last_name_filter = People.objects.filter(last_name='Doe').count()
first_name_filter = People.objects.filter(first_name='John').count()
实际上,版本A会导致对数据库的一次命中,而版本B会导致两次命中吗?
否,两者都将两次命中数据库。
People.objects.all()
不进行查询。事实上,QuerySet
是懒惰的。这意味着,除非您对其进行迭代、对其进行callen(…)
等操作,否则不会对数据库执行查询。因此,它基本上是一个等待执行的查询,除非有必要。
即使执行了people_var = Person.objects.all()
,也不意味着.filter(…)
函数将使用该缓存。事实上,如果您在QuerySet
上调用.all()
或.filter(…)
,则会生成一个新的、未求值的QuerySet
。
最后,如果您调用.count()
而不生成QuerySet
,则会生成SELECT COUNT(*) FROM …
查询。因此,在这里,您可以进行两个单独的查询,每个查询都将计算对象的数量。即使两个查询相同,Django也会进行两个查询。数据库可能会更快地回答第二个查询,但在两种情况下都是一样的。