在Django中缓存查询

时间:2011-01-11 17:44:15

标签: django caching

在django项目中,我只需要缓存一些查询,因为服务器的限制,使用缓存表而不是memcached。

其中一个查询如下:

假设我有一个Parent对象,它有很多Child个对象。 我需要存储简单查询parent.childs.all()的结果。

我对此没有任何问题,并且一切都按照预期的方式运行,例如

key = "%s_children" %(parent.name)
value = cache.get(key)
if value is None:
  cache.set(key, parent.children.all(), CACHE_TIMEOUT)
  value = cache.get(key)

但有时,有时,cache.set无效,并且在执行cache.set后,cache.get(key)会一直返回None

经过一些测试后,我注意到cache.set值较高时parent.children.all().count()无效。
这意味着如果我存储在key(例如)600个子对象内部,它可以正常工作,
但它不适合1200名儿童。

所以我的问题是密钥可以存储的数据是否有限制?我该如何覆盖它?


<小时/>
第二个问题:哪种方式“更好”,上面的代码还是以下代码?

key = "%s_children" %(parent.name)
value = cache.get(key)
if value is None:
  value = parent.children.all()
  cache.set(key, value, CACHE_TIMEOUT)

如果cache.set不起作用,第二个版本不会导致错误,因此它可能是我的问题的解决方法,但显然不是解决方案。

一般来说,让我们忘记我的问题,您认为哪个版本“更好”?

3 个答案:

答案 0 :(得分:2)

你的后端是MySQL吗?

在MySQL中,TEXT字段are limited to 65,000 bytes但django将使用此类型作为值字段。

INSERT&amp;如果你的数据太大,UPDATE查询将无声地失败。

我的建议是保持数据量小。存储完整的QuerySet似乎有点矫枉过正。你不能只存储必填字段吗?

喜欢这个查询

resultset = parent.children.values_list(*fields).all()

将获取所需的字段,而不是完整的实例。

答案 1 :(得分:0)

我看到三种可能性。第一个看起来最有可能发生在我身上,因为你说过你在资源有限的情况下运行:

  1. 可能需要很长时间才能获取您的查询,对其进行编码,然后再次存储 - 只要您的Web服务器进程耗尽内存或超时并在数据保存之前消失。

  2. 或者,可能是您的数据库对文本列的长度有一些相当小的限制,并且存储1200个base64编码的pickle对象超出了该限制。

  3. 也许您的缓存键超过255个字符。

答案 2 :(得分:0)

关于memcached的时髦之处 - 它对于可以存储在给定缓存键中的内容有1mb的限制。您可以配置此限制,但如果您在无法控制此默认值的服务器上进行部署,则会影响代码的可移植性。

请参阅此处的“存储数据列表”:http://code.google.com/p/memcached/wiki/FAQ