Datomic超过GC开销限制

时间:2016-02-02 10:27:09

标签: garbage-collection datomic

尝试使用此查询计算datomic中的实体

(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]]

使用dev后端。

我做错了什么,或者我应该尝试不同的后端或其他什么?

这是stacktrace http://pastebin.com/C76mEhEJ,它位于datomic.datalog内的某个地方。

1 个答案:

答案 0 :(得分:1)

Datomic中的查询非常热心。即使使用聚合,也将实现整个中间表示。在您的情况下,这是数据库中所有实体的entity-id,type,value部分的所有元组的集合。当整个中间集不能在内存中实现时,你会看到这样的错误,但是你的查询结构并不是Datomic可以天真地告诉他们将进行数据库扫描的结构(在这种情况下它将投掷。)

如果您要扫描整个数据库,datoms - 记录here - 更合适,因为它会懒散地遍历与前缀匹配的所有数据。对于您的用例,使用datoms进行数据库扫描的延迟seq方法可能类似于:

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

这将从:aevt索引中获取具有属性:type的所有数据(该属性是一个缩小结果的主要组件)。我们将datoms输出作为seq处理,并从每个数据中获取:e(实体ID),重复数据删除,因此我们只计算唯一实体。如果这是一个基数属性,则可以避免此dedupe步骤。