2011-04-14 68 views
1

我生成一个合并了许多用户评论的提要,因此您的提要可能是user1 + user2 + user1000的评论,而我的用户可能是user1 + user2。所以,我也行:合并缓存的GQL查询而不是使用输入

some_comments = Comment.gql("WHERE username IN :1",user_list) 

我不能只是内存缓存整个事情,因为每个人都会有不同的饲料,即使user1和user2的饲料是常见的许多观众。据the documentation

... IN操作符执行列表中的每一个 项单独 底层数据存储查询。返回的实体 是所有基础 数据存储查询的 交叉产物的结果,并且是 未重复的。对于任何 单个GQL查询,最多允许30个数据存储区查询。

是否有一个库函数合并一些分类和缓存的查询,还是我将不得不:

for user in user_list 
    if memcached(user): 
    add it to the results 
    else: 
    add Comment.gql("WHERE username = :1",user) to the results 
    cache it too 
sort the results 

(在最坏的情况下(没有什么是缓存)我预计发送30个GQL查询关闭比一个巨大的IN查询慢)

回答

1

您可以使用memcache.get_multi()来查看哪些用户的供稿已经在memcache中。然后使用原始用户列表上的set().difference()与在memcache中找到的用户列表找出哪些未被检索。然后,最后从批处理获取数据存储区中的缺失用户订阅源。

从那里你可以结合这两个列表,如果它不是太长,将它排序在内存中。如果你正在研究Ajaxy,你可以将其分类给客户端。

2

没有什么内置的功能可以做到这一点,但是您可以自己动手做,只需要注意一点:如果您执行in查询并返回30个结果,这些将是根据您的排序标准排序最低的30条记录所有的子查询。但是,如果您想从缓存的单个查询中组合结果集,那么要么必须为每个用户缓存多个结果集(例如30),并丢弃大多数结果集,否则,将不得不为每个用户存储更少的结果,并且接受有时您会抛弃一个用户的较新结果而偏向另一个用户的较旧结果。

这就是说,这里是你如何能做到这一点:

  1. 做一个memcache.get_multi检索缓存的结果集的所有用户
  2. 对于没有设置缓存结果的每个用户,执行个人查询,获取您需要的最多结果。使用memcache.set_multi来缓存结果集。
  3. 在所有结果集上进行合并连接,并将前n个结果作为最终结果集。由于用户名大概不是列表字段(例如,每个评论都有一个作者),所以您不必担心重复。

目前,in查询串行执行,所以当没有任何结果被缓存这种方式会不会比执行的in查询速度较慢,甚至。不过,这可能会在未来发生变化。如果您现在想提高性能,可能需要使用Guido的NDB项目,这将允许您并行执行所有子查询。