按键查询并迭代AppEngine中的对象

时间:2011-09-17 01:16:04

标签: python google-app-engine

AppEngine文档指出“返回密钥的查询比返回完整实体的查询更快,成本更低。”

这两个中哪一个是从数据存储中获取和迭代多个对象的更理想方式?

query_keys = Person.all(keys_only=True)
query_keys.filter('name = ', person_name)
query_keys.order("__key__")

people = db.get(query_keys)                                                
for p in people:
   #read properties of the person object
   print p.name

Vs

query = Person.all()
query.filter('name = ', person_name)                   
query.order("__key__")

for p in people:
   #read properties of the person object
   print p.name

3 个答案:

答案 0 :(得分:2)

常规查询基本上执行第一个代码段所执行的操作,仅在单个RPC内执行。如果你需要这些实体,那么只要求它们就更有效率,而不仅仅是要求密钥并自己获取实体。

要注意效率方面的一件事是迭代Query对象。执行此操作时,基础RPC层以20个批次从数据存储中获取结果,从而导致大量不必要的RPC。如果您知道需要多少结果,则应在查询上调用fetch()(如results = Person.all().filter('name =', 'Joe').fetch(100)),这只会执行一个RPC。

Appstats是发现和诊断这些性能问题的绝佳工具。

答案 1 :(得分:1)

当您正在阅读完整实体无论如何时,第二种方式至少不会比第一种方式慢。可能它会更快,因为它有更少的api调用

答案 2 :(得分:1)

仅密钥查询为您提供密钥,而不是具有属性的实体。在第一个示例中,p不会有.name。此外,密钥顺序是隐含的。如果您想要实体的属性,那么仅限键的查询就不是您想要的;你将不得不查询该实体。目前无法获得少于所有属性的因素,因此请将其纳入数据建模。

这是第三种选择,您可能会或可能不会发现更具可读性。它将与你的第二个片段等效地执行。

people = Person.gql("WHERE name=:1", person_name)
for person in people:
    print person.name

无论您使用此方法还是第二个代码段,直接查询实体都会比查询其密钥更快,然后获取与这些密钥对应的实体。