开发者

Queries by key and iterating over objects in AppEngine

AppEngine docs note that "Queries that return keys are faster and cost less CPU than queries that return full entities."

Which of these two is the more desired way to fetch and iterate over a number of objects from the data store?

query_keys = Person.all(keys_only=True)
query_keys.filter('name = ', person_name)
query_keys开发者_StackOverflow中文版.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


A regular query performs essentially the operations that your first snippet does, only inside a single RPC. If you need the entities, it's more efficient to just ask for them, than to ask for just the keys and fetch the entities yourself.

One thing you should watch out for efficiency-wise is iterating over Query objects. When you do this, the underlying RPC layer fetches results from the datastore in batches of 20, resulting in a lot of unnecessary RPCs. If you know how many results you need, you should call fetch() on the query (like results = Person.all().filter('name =', 'Joe').fetch(100)), which will only execute a single RPC.

Appstats is an excellent tool for discovering and diagnosing these sorts of performance issues.


As you're reading full entity anyway, then second way will be at least not slower that first one. Probably it will be faster, because it have less api calls


A key-only query gives you keys, not an entity that has properties. In the first example, p won't have a .name. Also, key order is implicit. If you want properties from an entity, a key-only query isn't what you want; you're going to have to query for the entity. There's no way at present to get less than all properties, so factor that in to your data modeling.

Here's third alternative, which you may or may not find more readable. It'll perform equivalently to your second fragment.

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

Whether you use this approach or your second snippet, querying directly for entities is going to be faster than querying for their keys, and then fetching the entities that correspond to those keys.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜