我的代码中有一个重复模式,其中模型有一个跟踪其历史/状态的相关模型(一对多)。这个相关模型可以有许多对象表示模型状态的时间点快照。Django ORM查询找到所有没有最近相关对象的对象
例如:
class Profile(models.Model):
pass
class Subscription(models.Model):
profile = models.ForeignKey(Profile)
data_point = models.IntegerField()
created = models.DateTimeField(default=datetime.datetime)
#Example objects
p = Provile()
subscription1 = Subscription(profile=p, data_point=32, created=datetime.datetime(2011, 7 1)
subscription2 = Subscription(profile=p, data_point=2, created=datetime.datetime(2011, 8 1)
subscription3 = Subscription(profile=p, data_point=3, created=datetime.datetime(2011, 9 1)
subscription4 = Subscription(profile=p, data_point=302, created=datetime.datetime(2011, 10 1)
我经常需要查询这些模型,找出所有没有在过去的3天或有类似的订阅更新“档案”的对象。我一直在使用子查询来完成这件事:
q = Subscription.objects.filter(created__gt=datetime.datetime.now()-datetime.timedelta(days=3).values('id').query
Profile.objects.exclude(subscription__id__in=q).distinct()
问题是,当涉及大型表时,这是非常缓慢的。有这样的查询更有效的模式吗?也许有些方法可以让Django使用JOIN而不是SUBSELECT(好像去掉所有那些内嵌的循环会有帮助)?
我宁愿使用ORM,但如果需要的话,我会愿意使用.extra()方法甚至原始SQL,如果性能提升足够引人注目。
我对Django 1.4alpha(SVN中继)和Postgres 9.1运行。
我跑测试查询和它非常缓慢(仍然在一小时后运行)。我在创建的字段上有一个索引。这个表虽然很大(5000万行左右)。 – erikcw
这就是您需要开始研究数据库优化的关键。为实例提供更多的RAM,将数据库移动到它自己的实例,如果它尚未被隔离,甚至建立一个集群,但是我刚刚给你的是最有效的你将会得到的优化查询本身。 –