2011-09-17 28 views
0

AppEngine文檔指出:「返回鍵的查詢比返回完整實體的查詢速度更快,成本更低。按鍵查詢並遍歷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 

回答

2

定期查詢基本上執行您的第一個代碼段所執行的操作,僅在單個RPC中執行。如果你需要這些實體,只需要詢問它們,而不是僅僅詢問密鑰並自己獲取實體。

爲了提高效率,您應該注意的一件事是迭代Query對象。當你這樣做時,底層的RPC層會從20個批次中獲取數據存儲的結果,從而導致大量不必要的RPC。如果您知道需要多少結果,則應在查詢(如results = Person.all().filter('name =', 'Joe').fetch(100))上調用fetch(),該查詢將僅執行一個RPC。

Appstats是發現和診斷這些類型的性能問題的極好工具。

1

當你正在閱讀全部的實體反正,那麼第二種方式將至少不慢於第一個。可能它會更快,因爲它有更少的API調用

+0

我正在閱讀實體上的2個屬性(並非全部)。 –

+0

btw,要從實體中獲取2個屬性,GAE需要從存儲中加載具有所有屬性的實體,不是嗎? –

1

只有鍵的查詢爲您提供密鑰,而不是具有屬性的實體。在第一個例子中,p將不會有.name。另外,鍵序是隱含的。如果你想要一個實體的屬性,一個只有鍵的查詢不是你想要的;你將不得不查詢實體。目前沒有辦法獲得比所有屬性都要少的東西,所以要考慮到數據建模。

這裏是第三種選擇,你可能會發現或不會發現更多的可讀性。它將等同於你的第二個片段。

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

無論你使用這種方法或你的第二個片段中,直接查詢實體將是比查詢自己的鑰匙,然後取對應於那些鍵的實體更快。

+0

'p'將會有一個名字,因爲它是'people'的一個元素,他使用'db.get'來獲取它。 –

+0

keys_only = True? –

+0

第5行。他提取對應於鍵的實體,然後遍歷這些實體。 –