Django QuerySets 和缓存

标签 django caching optimization query-optimization

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

def products(self, offset=None)

如果没有 offset通过,它只是返回所有对象(大约 5000 个,没有那么多)。如果有offest它返回带有偏移量的对象。

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

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

最佳答案

这取决于您尝试优化的位置。 Django caching (不要与 QuerySet caching 混淆,这是他们需要注意的行为的一个重要方面)当您想要跳过提供动态页面的动态部分时使用。因此,使用这些时的主要想法是(以及多长时间)我呈现给用户的内容不会改变?在优化您对产品的调用方面,functools.lru_cache将为您提供一个简单的内存缓存,但您主要关心的是使用 cache_clear() 破坏缓存的频率。要完全回答您的问题:
缓存通常不会受到伤害,但如果您没有注意到性能问题,也可能没有必要。如果您担心在使用 products() 时不会过多地敲打数据库,您可以利用 lru_cache 并且您需要决定何时/是否根据您的数据的性质来缓存 bust。话虽如此,数据库已针对此类检索进行了高度优化,根据您的应用程序,额外的逻辑可能不值得。此外,您还需要考虑您现在保留在持久存储中的内容有多少,以及这种权衡是否值得。
如果您不断地重新生成相同的页面以呈现给用户,请考虑使用 Django 缓存。跳过 products() 之前的步骤也只有在它们确实在一段时间内稳定时才有帮助。
就我个人而言,我会根据您所描述的内容单独留下 lru_cache(以及将额外缓存直接添加到您的数据库查询的任何想法)。这种内存缓存对于经常访问且必须计算一次的事物很有帮助,调用非常昂贵但产生相同的结果,您必须调用有费用的外部 API 的情况/are 不可靠等。如果在 ORM 前堆积复杂性之前,您似乎一直在向用户展示相同的页面,我会将其缓存到表示层 - 您可能希望您的经理实际与您的模型进行交互预期调用时。
跟进 12-10-16
自从有了这个答案,我就有机会使用 django cachalot并且发现如果您决定要缓存数据库查询,它会非常有效。它只需很少的努力即可设置,并且对文档中的权衡进行了精彩的探索。
跟进 08-05-20django_cachalot目前与最新的 Django (3.1+) 不兼容,所以我仍然不会推荐它,我目前也不使用它。如果您需要更重的 ORM 缓存,django_cacheops是当前和可行的。

关于Django QuerySets 和缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37188210/

相关文章:

ruby-on-rails - Rails 缓存清除

java - 无法在Java中创建缓存文件

Django admin 根据另一个字段值过滤一个外部字段

python - django 模板中的逗号分隔列表

django - 如何在网络应用程序中显示最近的项目以进行个性化?

c# - 优化多个网页的下载。 C#

performance - 您如何推断基准测试数据的波动?

python - Django:使用 Ajax 上传和保存文件

.net - WPF Image.Source 缓存过于激进

python - 查找包含图像的子文件夹