我有模特這樣描述的音樂專輯,請加入他們跟蹤,和個人監聽特定曲目:刪除多餘INNER從一個Django查詢
class Album(models.Model):
name = models.CharField(max_length=255)
class Track(models.Model):
name = models.CharField(max_length=255)
class Listen(models.Model):
track = models.ForeignKey('Track', related_name='listens', db_index=True)
album = models.ForeignKey('Album', related_name='listens', db_index=True, blank=True)
要獲得一個相冊,通過有序的所有曲目他們已經聽過的次數,我可以這樣做:
Track.objects \
.annotate(listen_count=models.Count('listens', distinct=True)) \
.filter(listens__album=1294) \
.order_by('-listen_count')
這得到正確的結果,但它似乎效率不高。結果查詢的簡化版本是:
SELECT track.id,
track.name,
COUNT(DISTINCT listen.id) AS listen_count
FROM track
LEFT OUTER JOIN listen ON (track.id = listen.track_id)
INNER JOIN listen T3 ON (track.id = T3.track_id)
WHERE T3.album_id = 1294
GROUP BY track.id, track.name
ORDER BY listen_count DESC
我可以失去的是INNER JOIN
得到相同的結果:
SELECT track.id,
track.name,
COUNT(DISTINCT listen.id) AS listen_count
FROM track
LEFT OUTER JOIN listen ON (track.id = listen.track_id)
WHERE listen.album_id = 1294
GROUP BY track.id, track.name
ORDER BY listen_count DESC
使用少了一個指數,是大約一半的速度。但我無法弄清楚如何讓Django ORM來做到這一點。 (我目前使用的SQLite,如果有差別,但將在以後使用PostgreSQL。)
做過濾1,然後註釋+訂單 – Todor