1

我正在運行一個keys_only查詢,該查詢獲取20個結果。如何在調用get_multi時阻止應用程序調用datastore_v3.next()?

result_keys, cursor, more = ActivityIndex.query(cls.followers == key)\ 
             .order(-cls.date_created)\ 
             .fetch_page(num_results, 
                start_cursor = cursor, 
                keys_only=True) 

我再拿到activityIndex對象的父母:

keys = [] 
for k in result_keys: 
    for pair in k.parent().pairs(): 
     keys.append(ndb.Key(pairs=[pair])) 

activities_related = ndb.get_multi(keys) 

我想這將是快速的,因爲我被重點得到了一批對象。但是,該查詢似乎呼叫datastore_v3.Next,根據appstats docs是「不良」,並佔用了執行時間的很大一部分。

避免不必要的下一步可能會調用您的應用程序加速!

爲的Appstats上述查詢(具有get_multi呼叫) Appstats view with get_multi enabled

將Appstats以上查詢,但沒有呼叫get_multi(短時間的next()響應)。 short time for next to respond

爲什麼在調用get_multi()datastore_v3.next()調用需要很長時間才能執行?它取決於get_multi將返回的結果數量嗎? get_multi中返回的一些對象具有列表屬性(列表中最多包含10個項目),這會在性能中起作用嗎?

爲了避免這個問題,倒不如改變設計,並在微進程獲取所需的實體?還有其他建議嗎?

編輯: 我在我的應用程序,例如顯示所有用戶活動的活動流:什麼,我試圖做

更多的信息Rob對圖片等進行了評論 爲了顯示這些信息,我想我需要用戶對象和圖片對象來構建活動描述和信息來顯示。我將所有這些對象的鍵設置爲ActivityIndex的父項。所以從上面的查詢中,ndb.get_mult(keys)將獲取Activity,User和Picture對象。 該鍵列表可以包含50項以上,所以這將可能會被長期datastore_v3.Next呼叫的原因。

回答

2

你在dev_appserver這樣做呢? (我希望不會,因爲它的表現完全與生產環境無關,所以我們都會浪費時間來討論這個問題。)

看起來有點可疑。 ISTR Next調用是異步調度的,在某些情況下實際上並不需要。這可以解釋,即使你沒有重疊調用,第一個圖表顯示Next重疊了memcache get調用。

但儘管如此,不應該有太大的延遲。在調用get_multi()之前,你是否正在做額外的東西?

BTW你與對做看起來過於複雜。如果有父母有一對以上,這將產生無效的密鑰。我認爲只有一個級別的父母,你只是想獲得這些 - 如果這是這樣,這應該是足夠了:

keys = [k.parent() for k in result_keys] 

最後,看問題118:http://code.google.com/p/appengine-ndb-experiment/issues/detail?id=118 - 我們測量的伎倆你似乎是在嘗試,只有當你的命中率很高時才值得。

+0

感謝您的回覆@Guido。我在現場服務器上這樣做。關於額外的東西;只有請求處理程序並從會話中獲取user_key。關於配對過於複雜;我編輯了我的問題來解釋我正在嘗試使用這些對。不過,我認爲我需要重新設計,並可能在tasklets中獲取這些額外的實體或者非規範化。 –

+0

如果鍵列表中包含超過50個鍵,是否會導致long datastore_v3.Next()調用? –

+1

IIUC您濫用父鍵對 - 實際的父項實際上並不存在。這不是如何使用父密鑰,我不知道這是如何影響數據存儲性能的。如果在一個關鍵字中確實有50對,那麼對於數據存儲區來說,這將顯示爲非常深的嵌套且非常長(並且沒有意義)的關鍵字,因此可能確實需要多個批次才能獲取結果。我認爲你應該重新考慮這一點。也許投影查詢可以幫助你? –

相關問題