我正在使用Django 1.7和GeoDjango创建一个网站。我已经到了需要优化网站速度的地步。
瓶颈之一是查询执行。有些查询即使在优化后运行也很慢。所以我想缓存查询结果并将它们存储在 Redis 中。
我遇到的问题是我无法缓存某些查询结果。特别是那些包含几何类型和距离计算的。我点击了"类型错误:无法腌制二进制对象"错误。
缓存Django/GeoDjango QuerySets的推荐/正确方法是什么?
事实证明,存储查询集的主要问题是:
- 查询集是懒惰的
- 要评估它们,您需要序列化它们[链接]
- 并非所有的 QuerySet 都可以序列化,因为 Python 的序列化器(泡菜(有其自身的局限性 [链接]
我发现的最佳解决方案是在模板中缓存查询结果。
所以在我的模板"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()
此方法很好,因为存储在缓存中的数据采用预期的文本形式。因此,在存储数据时应该没有问题/异常。
主要缺点是:
缓存可能包含重复的类似数据。当您缓存包含语言翻译字符串等的 html 片段时,可能会发生这种情况。因此,在某些情况下,您必须使用语言作为生成缓存的参数。如果您有 2 种语言的翻译,您将拥有相同数据的 2 个缓存。
在对 html 进行更改时,您必须使缓存失效。如果您正在缓存的代码块中的 html 不断变化,这可能会变得非常痛苦。
我个人认为问题1(没什么大不了的。问题 2( 可以通过对站点结构进行良好的规划并知道您可以在 Redis 中对缓存键进行大规模失效来避免。[链接]这是可能的,因为缓存以以下键格式存储:":1:template.cache.slow_query.8a5b358dfc28a6bc1b3397e398d28b66"
因此,应该可以删除与某些缓存块相关的所有缓存键。