Django objects.all()进行360多个查询 - 如何优化这个ManyToMany?

时间:2011-04-30 17:29:38

标签: django

Django新手,今天就此提出第三个问题......

我定义了以下(简化)模型:

class Band(models.Model):
    bandname = models.CharField('Band name', max_length=300)

class Release(models.Model):
    title = models.CharField(max_length=300)
    artist = models.ManyToManyField('Band')
    formats = models.ManyToManyField('Format')

class Format(models.Model):
    kind = models.CharField(max_length=300)

class Song(models.Model):
    title = models.CharField(max_length=500)
    release = models.ForeignKey('Release')

(为了便于阅读,我删除了额外的字段)

现在,当我尝试运行以下查询时,它会向页面添加数百个额外查询:

s = Song.objects.all() # adds 367 queries

我已经尝试将其更改为:

s = Song.objects.select_related('band', 'release').all() # adds 245 queries

这仍然很糟糕,我不知道我还能做些什么。我的数据库中有122首歌曲,52个版本,39个乐队。不确定这是否有帮助,但我不知所措。

有关如何优化此功能的任何提示?我需要能够显示每个Song的乐队和发行名称。 Release的{​​{1}}是ManyToMany,因为其中一些是多位艺术家的拆分版本。

感谢, 马特

1 个答案:

答案 0 :(得分:1)

Django select_related不遵循多对多关系,我猜这是造成大量查询计数的原因。

我的建议是使用values()double__underscore__notation来获取所需的值。类似的东西应该适用于django 1.3及以上版本:

s = Song.objects.values('title', 'release__title', 'release__artist__bandname')