【发布时间】:2019-08-19 09:50:12
【问题描述】:
这是我的模型:
class Event(models.Model):
user = models.ForeignKey(User, blank=True, null=True, db_index=True)
name = models.CharField(max_length = 200, db_index=True)
platform = models.CharField(choices = (("ios", "ios"), ("android", "android")), max_length=50)
class User(AbstractUser):
email = models.CharField(max_length=50, null=False, blank=False, unique=True)
Event 就像一个分析事件,所以如果一个用户在多个设备上登录,我很可能会为一个用户创建多个事件,有些是 platform=ios,有些是 platform=android。我想查询有多少用户同时拥有 ios 和 android 设备。所以我写了一个这样的查询:
User.objects.filter(Q(event__platform="ios") & Q(event__platform="android")).count()
返回 0 个结果。我知道这是不正确的。然后我想我会尝试只查询 iOS 用户:
User.objects.filter(Q(event__platform="ios")).count()
返回 6,717,622 个结果,这是出乎意料的,因为我只有 39,294 个用户。我猜这不是计算用户,而是计算Event 实例,这对我来说似乎是不正确的行为。有人对这个问题有任何见解吗?
【问题讨论】:
-
第二个查询看起来不错,尝试在 count 之前添加
.order_by()以删除任何默认排序,然后查看它是否有效。模型的Meta中定义的默认排序可能会以微妙的方式破坏您。 -
我添加了
.order_by('user_id'),结果相同。起作用的是添加.distinct('id'),尽管查询仍然需要很长时间。我的猜测是,如果不扁平化我的数据库结构,我不会让它更快。 -
我假设您在
platform上已经有一个index。 Navid 建议使用整数而不是字符串也有帮助。最后,不使用连接但只访问Event表的原始 SQL 应该可以将查询速度提高两个数量级(同时对于这种大小的表仍然不会产生即时结果)。 -
2个数量级应该是完美的。
标签: sql django django-queryset django-q