如何提高gae查询的性能?

时间:2016-09-09 07:16:31

标签: python performance google-app-engine google-cloud-datastore app-engine-ndb

我已经实现了查询表的逻辑,对于该特定表中的每个实体,我必须查找另一个表。

For,ex。

我的代码看起来像,

query = ndb.gql("select * from Foo where user = :1", user.key)
stories, next_cursor, more = query.fetch_page(size, start_cursor=cursor)
if next_cursor:
   for story in stories:
       print story.key
       images = ndb.gql("select * from Images where story = :1", story.key)
       for image in images:
           print image.key
else:
   #do some operations

你知道,如果我们将fetch_page函数的大小设为10,它将分别找到10个实体。对于每个实体,我们必须查找另一种Image

此类型的数据存储查找需要850到950毫秒。我想减少这个API的响应时间。 请注意,我必须从Story种类和Images种类获得一些列值。

无论如何都要使用get_multi方法来缩短查询。或者,我知道使用memcache或者我们应该在StructuredProperty模型中定义新的Foo,其值必须是Images模型实体的列表。

我不知道哪一个适合这种情况..请指导我。

3 个答案:

答案 0 :(得分:2)

您可以为包含图片ID列表的每个Story添加属性。我认为这个列表很少改变。然后,您可以轻松get_multi所有与故事相关的图像,而无需任何疑问。

您还可以考虑get_multi所有故事的所有图片,通过您的查询返回,只需一次通话,然后根据需要将其“附加”到代码中的相应故事中。

答案 1 :(得分:1)

我不知道你项目的整体结构,但是......

你可以这样做:

class Story(ndb.Model):
    images = ndb.KeyProperty(kind=Image, repeated=True)
    user = ndb.KeyProperty(kind=User)

每次用户添加新图片时都会更新images的{​​{1}}属性。

然后你就可以使用:

Story

希望有所帮助。

答案 2 :(得分:1)

您需要查看NDB批处理异步API

   @ndb.tasklet
   def get_stories(user_key):
     stories = yield Story.query(Story.user_key == user_key).fetch_async()
     futs = [
       item.key.get_async() for item in stories]
     result = yield futs
     raise ndb.Return(result)

   get_stories(user_key).get_result()

此API只会调用2个查询。

  1. 对DataStore进行查询
  2. 使用上述查询的N结果,进行1次查询以获取所有故事
  3. 因为,Key.get_async()也自动使用memcache,从你调用上面的函数的秒数开始,2查询将调用memcache