2016-02-02 152 views
0

試圖計數datomic實體與此查詢Datomic超出GC開銷限制

(d/q '[:find (count ?a) . :where [?a :type]] (d/db (conn))) 

OutOfMemoryError GC overhead limit exceeded [trace missing] 

工作想如果我試着算像

(d/q '[:find (count ?a) :where [?a :type "psp"]] (d/db (conn))) 

[[400541]] 

較小的子集使用開發後端。

它是我做錯了什麼,或者我應該嘗試不同的後端,還是別的?

這裏是堆棧跟蹤http://pastebin.com/C76mEhEJ這導致datomic.datalog內的某處。

+0

你的堆設置是什麼?這看起來像你沒有足夠的內存用於中間表示(仍然是一組元組,儘管你已經集合了它)。 –

+0

@BenKamphaus如果我正確地理解了jvm選項,我的初始和最大堆大小是2Gb和4Gb,這裏是jvm輸出http://pastebin.com/eRpEXEuv,試圖用「-Xmx6g」「-Xms4g」運行,結果和這幾乎是我所有的公羊。順便說一句,你是什麼意思的中間結果,'?a'(整個數據集)在我的情況? – cvb

+1

是的,Datomic中的查詢是渴望的,查詢中的聚合對所有匹配[_:type _ _ _]的元組進行操作。你可以嘗試使用datoms進行數據庫掃描的懶序列操作,例如:(count(dedupe(map#(:e%)(seq(d/datoms(d/db conn):aevt:type)))) )' –

回答

1

Datomic中的查詢很渴望。即使在使用聚合時,也會實現整個中間表示。在你的情況下,這是數據庫中所有實體的entity-id,type,value部分的所有元組的集合。當整個中間集無法在內存中實現時,您會看到類似這樣的錯誤,但是您的查詢結構不是Datomic可以天真地告訴將要進行數據庫掃描(在這些情況下會拋出)的結構。

如果你正在掃描整個數據庫,datoms - 記錄here - 是一個更好的選擇,因爲它會懶洋洋地遍歷所有匹配前綴的數據。對於DB掃描與datoms懶惰序列的方法爲您的使用情況下,可能是這樣的:

(count (dedupe (map #(:e %) (seq (d/datoms (d/db conn) :aevt :type))))) 

這得到所有datoms從具有屬性:type(該屬性是然後縮小的主要成分:aevt指數結果)。我們將datoms輸出作爲seq處理,並從每個數據庫中獲取:e(實體ID),並進行重複數據刪除,以便我們只計算唯一的實體。如果這是一個基數屬性,你可以避免這個步驟dedupe

相關問題