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