Django QuerySets和缓存

问题描述 投票:3回答:1

我在一些对象管理器中有一个方法,它从db获取数据:

def products(self, offset=None)

如果没有传递offset,它只返回所有对象(大约5000,不是那么多)。如果有offest它会返回具有偏移量的对象。

这种方法在应用程序生命周期中使用了很多。我想以某种方式缓存其结果是合理的。

我的问题是:functools.lru_cache会做这个工作还是我应该考虑使用Django的缓存?或者也许我不应该过早地考虑它?

django caching optimization query-optimization
1个回答
9
投票

这取决于您尝试优化的位置。当你想跳过提供动态页面的动态部分时,会使用Django caching(不要与QuerySet caching混淆,这是他们行为的一个重要方面)。那么使用它们时的主要思想是,我向用户呈现的内容是否会(并且持续多长时间)不会改变?在优化您对产品的调用方面,functools.lru_cache将为您提供简单的内存缓存,但您主要关注的是使用cache_clear()来缓存缓存的频率。完全回答你的问题:

缓存通常不会受到影响,但如果您没有注意到性能问题,也可能没有必要。如果您担心在使用products()时没有如此多地锤击数据库,您可以利用lru_cache并且您需要决定何时/是否缓存由数据性质决定的半身像。话虽这么说,数据库针对此类检索进行了高度优化,根据您的应用程序,可能不值得额外的逻辑。另外,你会想要考虑持久存储中有多少东西,你现在保留在内存中,如果这种权衡是值得的。

如果您不断重新生成相同的页面以呈现给用户,请查看使用Django缓存。跳过产品()之前的步骤也只有在它们确实陈旧一段时间后才有用。

就个人而言,我会根据你所描述的内容单独留下lru_cache(以及任何直接向db查询添加额外缓存的想法)。这种内存中缓存对于经常访问并且必须一次计算的事情有用,调用非常昂贵但产生相同的结果,在这种情况下你必须调用有费用的外部API如果看起来你在向ORM堆积复杂性之前不断向用户呈现相同的页面,我会缓存到表示层 - 你可能希望你的经理实际上与你的模型交互预计在被召唤时。

后续12-10-16

由于这个答案,我有机会使用django cachalot,并且发现如果您确定要缓存数据库查询,它的效果非常好。它需要很少的设置工作,并对文档中的权衡进行了精彩的探索。

© www.soinside.com 2019 - 2024. All rights reserved.