假设我们有一个模型
class Person(models.Model):
is_gay = models.BooleanField()
is_tall = models.BooleanField()
is_nice = models.BooleanField()
...
现在假设我们想知道我们有多少人符合不同的标准。我们可以通过计算它们来达到这个目的
num_gays = models.Person.objects.filter(is_gay=True).count()
num_tall_and_nice = models.Person.objects.filter(is_tall=True, is_nice=True).count()
不幸的是,这将需要2个数据库查询。正如你所想象的,随着类型的人越来越多(例如25/30的计数),这可能会减慢很多。
所以现在我们可以通过使用聚合来优化
aggregations = {}
when = models.When(is_gay=True, then=1)
case = models.Case(when, output_fields=models.IntegerField())
sum = models.Sum(case)
aggregations['num_gays'] = sum
when = models.When(is_tall=True, is_nice=Ttrue, then=1)
case = models.Case(when, output_fields=models.IntegerField())
sum = models.Sum(case)
aggregations['num_tall_and_nice'] = sum
result = models.Person.objects.aggregate(**aggregations)
但是,我很好奇Django(使用MySQL)如何处理这个查询。
它只查看表一次吗?每次查看行时,它都会将
1
添加到应用的每个CASE语句中。或者看看表N
乘以N
是CASE语句的数目吗? 最佳答案
不,这只是一个查询。因为django Case/When或多或少直接转换成mysql Case/When。然而,当您有疑问时,您总是可以找出django使用这段代码执行了哪些查询
from django.db import connection
print connection.queries
不带where子句的任何查询和RDBMS都会检查整个表。将查看表中的每一行。此查询似乎没有where子句。
但是对于执行的查询的数量。正好是1