Datomic 超过 GC 开销限制
Datomic exceed GC overhead limit
尝试使用此查询对数据中的实体进行计数
(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
.
中的某处
Datomic 中的查询很急切。即使在使用聚合时,也会实现整个中间表示。在您的情况下,这是数据库中所有实体的实体 ID、类型、值部分的所有元组的集合。当整个中间集无法在内存中实现时,您会看到这样的错误,但您的查询结构不是 Datomic 可以天真地告诉将进行数据库扫描的结构(在那些情况下它会抛出)。
如果您正在扫描整个数据库,datoms
- 记录在案 here - 更适合,因为它将懒惰地遍历与前缀匹配的所有数据。对于您的用例,使用 datoms
进行数据库扫描的惰性 seq 方法可能类似于:
(count (dedupe (map #(:e %) (seq (d/datoms (d/db conn) :aevt :type)))))
这会从 :aevt
索引中获取所有具有属性 :type
的数据(该属性是缩小结果范围的前导组件)。我们将 datoms
输出处理为 seq
,并从每个数据中获取 :e
(实体 ID),进行重复数据删除,因此我们只计算唯一实体。如果这是一个基数属性,您可以避免此 dedupe
步骤。
尝试使用此查询对数据中的实体进行计数
(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
.
Datomic 中的查询很急切。即使在使用聚合时,也会实现整个中间表示。在您的情况下,这是数据库中所有实体的实体 ID、类型、值部分的所有元组的集合。当整个中间集无法在内存中实现时,您会看到这样的错误,但您的查询结构不是 Datomic 可以天真地告诉将进行数据库扫描的结构(在那些情况下它会抛出)。
如果您正在扫描整个数据库,datoms
- 记录在案 here - 更适合,因为它将懒惰地遍历与前缀匹配的所有数据。对于您的用例,使用 datoms
进行数据库扫描的惰性 seq 方法可能类似于:
(count (dedupe (map #(:e %) (seq (d/datoms (d/db conn) :aevt :type)))))
这会从 :aevt
索引中获取所有具有属性 :type
的数据(该属性是缩小结果范围的前导组件)。我们将 datoms
输出处理为 seq
,并从每个数据中获取 :e
(实体 ID),进行重复数据删除,因此我们只计算唯一实体。如果这是一个基数属性,您可以避免此 dedupe
步骤。