Django的查询结果缓存

时间:2014-12-01 16:43:13

标签: django pickle django-cache django-caching django-redis

我正在使用Django 1.7和GeoDjango创建一个网站。当我需要优化网站速度时,我已经达到了目的。

其中一个瓶颈是查询执行。有些查询即使在优化时也会缓慢运行。 所以我想缓存查询结果并将它们存储在Redis中。

我得到的问题是我无法缓存一些查询结果。特别是包含几何类型和距离计算的那些。我点击“TypeError:无法腌制二进制对象”错误。

缓存Django / GeoDjango QuerySets的推荐/正确方法是什么?

1 个答案:

答案 0 :(得分:0)

结果表明存储查询集的主要问题是:

  1. QuerySets很懒惰
  2. 要评估它们,您需要序列化它们 [link]
  3. 并非所有QuerySets都可以序列化,因为Python已经过了 序列化程序(Pickle)有自己的限制[link]
  4. 我找到的最佳解决方案是将查询结果缓存在模板中。

    所以在我的模板" sample.html"我写了类似的东西:

    {% cache 600 slow_query_results %}
    <!-- result of page generation -->
    {% endcache %}
    

    我认为:

    from django.core.cache import cache
    from django.core.cache.utils import make_template_fragment_key
    ...
    slow_query_results_key = make_template_fragment_key('slow_query_results')
    if not cache.get(slow_query_results_key):
        # return calculated result
        slow_query_results = perform_some_slow_query()
    

    此方法很好,因为存储在缓存中的数据是预期的文本形式。因此在存储数据时应该没有问题/异常。

    主要缺点是:

    1. 缓存可能包含重复的类似数据。当您缓存包含语言翻译字符串的html片段等时,可能会发生这种情况。因此,在某些情况下,您必须使用语言作为生成缓存的参数。如果您有2种语言的翻译,那么您将拥有2个相同数据的缓存。

    2. 在对html进行更改时,您必须使缓存无效。如果您缓存的代码块中的html不断变化,这可能会变得非常痛苦。

    3. 我个人认为问题1)并不是什么大问题。问题2)可以通过良好的站点结构规划和知道你可以在Redis中对缓存键进行大量失效来避免。 [link]这是可能的,因为缓存按以下密钥格式存储:":1:template.cache.slow_query.8a5b358dfc28a6bc1b3397e398d28b66"

      因此应该可以删除与某些缓存块相关的所有缓存键。