Django中的属性缓存 - 重点是什么?

时间:2009-07-19 17:22:49

标签: python django django-models

我只是查看EveryBlock的源代码,我在alerts / models.py代码中注意到了这段代码:

    def _get_user(self):
    if not hasattr(self, '_user_cache'):
        from ebpub.accounts.models import User
        try:
            self._user_cache = User.objects.get(id=self.user_id)
        except User.DoesNotExist:
            self._user_cache = None
    return self._user_cache
    user = property(_get_user)

我已经注意到这种模式,但我不太了解其用途。整个想法是确保在访问自己的FK(self = alert对象)时,你只从db中获取一次用户对象?你为什么不依靠db缓存amd django的ForeignKey()字段?我注意到模型定义只保存用户ID而不是外键字段:

class EmailAlert(models.Model):
     user_id = models.IntegerField()
     ...

任何见解都将不胜感激。

2 个答案:

答案 0 :(得分:2)

我不知道为什么这是一个IntegerField;它看起来肯定应该是一个ForeignKey(用户)字段 - 你在这里丢失了像select_related()这样的东西以及其他东西。

对于缓存,许多数据库不会缓存结果 - 它们(或者更确切地说,操作系统)会将数据缓存到获取结果所需的磁盘上,因此第二次查找它应该比第一次更快,但它仍然需要工作。

它还需要一个数据库往返查找它。根据我的经验,使用Django,执行项目查找可能需要大约0.5到1毫秒,对于本地Postgresql服务器的SQL命令加上有时非常重要的QuerySet开销。如果您不需要它,则需要1ms - 这样做几次,您可以将30ms请求转换为35ms请求。

如果您的SQL服务器不是本地的,并且您实际上有网络往返处理,则数字会变大。

最后,人们通常希望获得快速的物业;当它们足够复杂而导致SQL查询时,缓存结果通常是一个好主意。

答案 1 :(得分:2)

虽然数据库会在内部缓存内容,但每次要检查相关字段的值时都会返回数据库的开销 - 在Django中设置查询,连接到数据库的网络延迟以及返回网络上的数据,在Django中实例化对象等。如果你知道数据在此期间没有改变 - 并且在单个web请求的上下文中你可能不关心它是否有 - 它会做得更多感觉一次获取数据并缓存它,而不是每次都查询它。

我工作的其中一个应用程序有一个包含大量数据的极其复杂的主页。以前它正在执行超过400个db查询来呈现。我现在已经重构了它,所以它'只'使用80,使用与你发布的技术非常相似的技术,你最好相信它会带来巨大的性能提升。