在Django模型中,访问外键的速度是否比将其存储到临时变量要慢几倍?

时间:2012-05-30 02:34:09

标签: django performance django-models

E.g。机型:

class Player(models.Model):
    Team = models.ForeignKey(Team)

从效率的角度来看,如果您多次访问玩家的“团队”,将团队存储在临时变量中会更有效吗?

效率低下:

player = Player.objects.get(id=1)
print "Player is a member of " + str(player.team)
player.team.printRoster()

比这个?:

player = Player.objects.get(id=1)
temp = player.team
print "Player is a member of " + str(temp.team)
temp.printRoster()

我觉得答案是否定的,它们都是一样的。但是听到了同事的不同反馈意见并希望得到一个客观的观点。

2 个答案:

答案 0 :(得分:5)

指定here

Django为您缓存它。问题是你将如何处理这些“外键”引用。例如,如果你有一个模型的外键,其 unicode 方法访问另一个外键来打印“友好”的unicode字符串,这取决于你如何创建查询集,你可能会再次访问数据库

让我举个例子来澄清:

class Player(models.Model):
    pname = models.CharField(max_length=20)
    team = models.ForeignKey('Team')

class Team(models.Model):
    tname = models.CharField(max_length=20)
    country = models.ForeignKey('Country')

    def __unicode__(self):
        return self.tname + u' is from ' + self.country.cname

class Country(models.Model):
    cname = models.CharField(max_length=10)

执行此操作时:

player = Player.objects.get(name=u'Messi')
print player.team

你会三次点击数据库,一次是获取玩家,另一次获得团队,另一次获取国家名称。如果我没错,下次你做那个“打印”声明时,django就不会再次打到数据库了(我可能错了,但我认为它的工作原理是这样的。)

现在想象一下,你想为每个玩家做这件事,你有很多。你将打算每个玩家三次打到数据库,这可能不是很好。如果稍微更改一下您的查询,您可以只执行一次命中数据库。这就是你如何做到的:

players = Player.objects.all().select_related('team__country')
for player in players:
    print player.team

我希望这有助于您了解查询集如何在Django上运行。尝试阅读我在此处链接的文档。一个可以帮助您衡量查询效率的优秀工具是django_toolbar。我强烈推荐它。

答案 1 :(得分:1)

Django为您缓存它,请检查the code

您可以通过检查

来确保这一点
>>> player.team is player.team