我的代碼中有一個重複模式,其中模型有一個跟蹤其歷史/狀態的相關模型(一對多)。這個相關模型可以有許多對象表示模型狀態的時間點快照。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,將數據庫移動到它自己的實例,如果它尚未被隔離,甚至建立一個集羣,但是我剛剛給你的是最有效的你將會得到的優化查詢本身。 –