1

我正在运行一个 keys_only 查询,它获取 20 个结果。

result_keys, cursor, more = ActivityIndex.query(cls.followers  == key)\
                                        .order(-cls.date_created)\
                                        .fetch_page(num_results,
                                                    start_cursor = cursor,
                                                    keys_only=True)

然后我得到activityIndex对象的父母:

keys = []
for k in result_keys:
    for pair in k.parent().pairs():
        keys.append(ndb.Key(pairs=[pair]))

activities_related = ndb.get_multi(keys)

我认为这会很快,因为我正在按键获取一批对象。但是,查询似乎 call datastore_v3.Next,根据appstats 文档,它是“坏的”,并且占用了很大一部分执行时间。

避免不必要的 Next 调用可能会加快您的应用程序!

上述查询的 Appstats(使用 get_multi 调用) 启用 get_multi 的 Appstats 视图

上述查询的 Appstats 但没有调用 get_multi(next() 响应时间短)。 下一个响应的时间很短

为什么datastore_v3.next()调用时调用需要这么长时间才能执行get_multi()?它是否取决于 get_multi 将返回的结果数量?get_multi 中返回的一些对象具有列表属性(列表中最多 10 个项目),这会对性能产生影响吗?

为避免此问题,是否最好更改设计并在 tasklet 中获取所需的实体?还有其他建议吗?

编辑:

关于我正在尝试做的更多信息:我的应用程序中有一个活动流,它显示所有用户活动,例如 Rob 对 Picture 等的评论。要显示此信息,我认为我需要 User 对象和 Picture对象来建立活动描述和要显示的信息。我将所有这些对象的键设置为ActivityIndex. 因此,从上面的查询中,ndb.get_mult(keys)将获取 Activity、User 和 Picture 对象。键列表可能包含 50 个或更多键,因此这可能是导致长时间datastore_v3.Next调用的原因。

4

1 回答 1

2

您是在 dev_appserver 中执行此操作吗?(我希望不会,因为它的性能与生产环境的性能完全无关,我们都在浪费时间讨论这个问题。)

似乎有什么可疑的事情发生了。ISTR 认为 Next 调用是异步安排的,在某些情况下实际上不需要。这可以解释即使您没有重叠调用,第一个图表显示 Next 重叠 memcache get 调用。

但是,仍然不应该有那么大的延迟。在调用 get_multi() 之前,您是否正在做您没有显示的额外内容?

顺便说一句,您对这些对所做的事情看起来过于复杂。如果有任何父母有一对以上,这将产生无效的密钥。我认为只有一个级别的父母,你只想得到那些——如果是这样,这就足够了:

keys = [k.parent() for k in result_keys]

最后,请参阅问题 118:http ://code.google.com/p/appengine-ndb-experiment/issues/detail?id=118 - 我们测量了您似乎正在尝试的技巧,只有当您的命中率真的很高。

于 2012-11-03T05:33:16.797 回答