簡體   English   中英

使用appengine數據存儲區祖先路徑進行高效搜索

[英]efficient searching using appengine datastore ancestor paths

我們有一個覆蓋租賃,我需要根據索引屬性范圍和客戶端ID搜索和獲取一個巨大的appengine數據存儲區。 Ancestor Paths的使用是否有效? 或者可以使用額外的過濾器完成相同的操作

例如,通過客體化獲得前100名工資

Key<Clients> clientIdKey = Key.create(Clients.class, 500)
ofy().load().type(Salaries.class).ancestor(clientIdKey).order("-salary").limit(100).list()

或者只是

ofy().load().type(Salaries.class).filter("clientId = ", 500 ).order("-salary").limit(100).list()

我的假設是,在第一種情況下,屬於任何其他客戶端的所有實體都將被忽略,但在以后的情況下,它將是全掃描,這將更加昂貴。 這個假設是對的嗎?

索引“salary”也是全局存儲的,還是根據祖先進行分區,以便索引更新只發生在同一個祖先中? 這將減少更新索引所需的時間,並且當我們永遠不會在不同客戶端之間進行查詢時,這將是一個很好的解決方案。

我需要指出的第一件事是數據存儲區不進行表掃描。 除了幾個例外(最明顯的是Z字形合並),GAE查詢只跟蹤索引 - 所以通常這些問題歸結為“哪個索引維護更有效?”

讓我們先談談第二種情況(注意我已經將Salary單一化了,我認為這是你的意圖):

ofy().load().type(Salary.class).filter("clientId = ", 500 ).order("-salary").limit(100).list()

這需要Salary { clientId, salary } DESC上的多屬性索引。 GAE將索引導航到Salary/clientId/500的開頭,然后一次讀取一個索引記錄。 它將在任意數據中心的索引表上執行此操作 - 並且由於這些索引表是異步復制的,因此可以獲得最終一致的結果。

為了使實體參與多屬性索引,必須自己為每個單獨的屬性編制索引。 如果Salary沒有其他索引屬性,則編寫單個Salary將花費:

  • 1寫入實體操作
  • 2寫入clientId索引(asc和desc)
  • 2寫入salary指數(asc和desc)
  • 1寫入多屬性索引{ clientId, salary } DESC

現在讓我們看看第一種情況:

ofy().load().type(Salary.class).ancestor(clientIdKey).order("-salary").limit(100).list()

這需要datastore-indexes.xml中的不同多屬性索引。 這次你需要一個關於Salary { ancestor, salary } DESC的索引。 此外,GAE的默認行為是從法定數量的中心讀取數據,以使其成為一致的操作。 這應該比其他方法稍慢(盡管不貴),但是,您可以明確指定最終一致性以獲得相同的“任何數據中心”行為: ofy().consistency(Consistency.EVENTUAL).load()...這里的好處是,你有強烈的一致性選擇。

祖先方法的另一個好處是您不需要在clientId上維護單屬性索引。 這是您編寫此薪水時所發生的情況(假設沒有其他索引字段):

  • 1寫入實體操作
  • 2寫入salary指數(asc和desc)
  • 1寫入多屬性索引{ ancestor, salary } DESC

這可以使您的系統更便宜。 多屬性索引的最大成本通常是所有(否則無關的)雙向單屬性索引的成本,您必須將其簡單地作為GAE的標志。


關於您的上一個問題,可能有助於解釋GAE索引表的外觀。 索引有三個BigTable表,在所有應用程序中共享。 前兩個是單屬性索引表(一個用於升序,一個用於降序)。 他們的內容看起來非常像這樣:

{appId}/{entityKind}/{propertyName}/{propertyValue}/{entityKey}

通過范圍掃描(BigTable的原始操作之一),您可以確定哪些實體與您的查詢匹配。 這也是僅限密鑰查詢快速/便宜的原因; 您可以立即返回密鑰,而無需進行后續查找。

多屬性索引表看起來(再次,這不完全),如下所示:

{appId}/{entityKind}/{prop1name}/{prop1value}/{prop2name}/{prop2value}/.../{entityKey}\

使用Salary { clientId, salary } DESC上的多屬性索引的某些值可視化可能更容易:

yourapp/Salary/clientId/500/salary/99000/aghzfnZvb3N0MHILCxIFRXZlbnQYAQw
yourapp/Salary/clientId/500/salary/98000/aghttydiisgAJJ3JGS0ij44JFAjasdw

再次,您可以看到通過執行范圍掃描,GAE可以找到與您的查詢匹配的實體。

我希望這有助於清理事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM