0

我在執行異步GAE NDB數據存儲查詢時遇到問題。出於測試目的,假設我執行異步GAE數據存儲查詢未正確觸發

l = [] 
for i in range (0,50): 
    qry = NDBNetLoc.query(NDBNetLoc.netloc == 'imdb.com').get() 
    l.append(qry) 

哪裏netloc是我的模型的索引屬性(沒有其他性能;我在這裏固定字符串,但一般查詢將是獨一無二的字符串)。這當然使得在請求「瀑布」:

http://imgur.com/a/uckrh#FAON8pZ

這是規範類型的請求應(根據谷歌)被async'd。相反,我執行

futs = [] 
for i in range (0,50): 
    qry = NDBNetLoc.query(NDBNetLoc.netloc == 'imdb.com').get_async() 
    futs.append(qry) 

for fut in futs: 
    l.append(fut.get_result()) 

但我沒有看到改善。雖然每個請求大火此起彼伏,每次調用花費更長的時間(持續時間減少爲i增加)

http://imgur.com/a/uckrh#eUVfLrG

此外,它好像請求沒有射擊,直到第二個for循環。如果我在這個循環的前面加上time.sleep(2),我得到的東西像

http://imgur.com/a/uckrh#SztJnkn

這是非常混亂給我,我馬上想到了請求火被創建未來的對象。所以我的兩個問題是1)爲什麼現在每個將來的對象實例化時請求都不會被觸發,2)爲什麼每個請求現在需要更長的時間(到了這種異步或同步執行時間相當於完)?

編輯: 我要補充一點,我沒有做一個簡單的IN查詢的唯一netloc個清單的原因是因爲,因爲我最終運行更復雜的查詢(即讓所有模型2的有propertyA = foo和一個祖先是從第一個查詢返回的特定NDBNetLoc,對於許多NDBNetLoc和許多foo)。

+1

**建議,可能會或可能不會適用於你的情況**:如果你是說你的字符串是獨一無二的,你可以使用他們作爲實體鍵,並做一個'get_multi',這將返回一個RPC請求中的所有50個結果,而不是50. – 2014-10-29 16:54:39

+0

這非常適用於我正在做的第一種類型的查詢。謝謝謝謝!對於一些更復雜的查詢(那些查詢屬性不是唯一的),我仍然需要使用正常的方式。我想我最終會轉移到Java,但由於時間限制,我會使用'get_multi'並在我的其他查詢中效率低下 – thegeebe 2014-10-29 18:20:23

回答

-2

我在SO上發現了這個問題的一個總結......我並不十分熟悉全局解釋器鎖以及它是如何應用於此的,但我想解碼RPC的代碼是CPython字節碼,而解釋器不是線程安全,以便每個調用都鎖定它。想我會搬過來到Java .....

AppEngine Query.fetch_async not very asynchronous?