Datomic entity-api 在大量实体上运行缓慢?
Datomic entity-api is slow on large amount of entities?
我需要对从 Datomic 获得的实体应用额外的逻辑(如映射、条件、聚合)。我很难将它转换为 Datomic 查询(我不确定在我的情况下是否可行),这就是为什么我改用 datomic 的原始索引访问,所以大部分工作和逻辑都是在 Clojure 中完成的。
在我达到约 500K 个条目之前,它工作正常,整个方法变得非常慢。
相关代码:
(defn e->entry
"Map e into entry"
[e]
{:id (:entry/uuid e)
;; each flat field increases mapping time (seems linearly)
:date (:entry/date e)
:summ (:entry/summ e)
;; although when using nested fields, mapping time rises significantly
:groups (map #(-> % :dimension/group :group/name)
(:entry/dimensions e))})
;; query code:
(->> (d/datoms db :aevt :entry/uuid)
(map #(->> %
:e
(d/entity db)
e->entry))))
;; TODO: other actions on mapped entries ...
它需要大约 30 秒 到 运行 查询代码来映射实体,我在查询中需要的字段越多,所需的时间就越多。
这是预期的行为吗?有什么方法可以加快速度,或者我是否遗漏了什么,这是不好的方法?
要完整回答此问题需要更多信息,请随时 ask on the forum or open a support ticket。
我最终进行了以下优化,以防有人需要它:
(defn eid->entry
"Mapping via :eavt index"
[db eid]
(->> (d/datoms db :eavt eid) ; access all datoms by eid once
(seq)
(reduce (fn [m dtm]
(let [attr-key (d/ident db (:a dtm))
v (:v dtm)]
(assoc m attr-key v))))))
;; new query code
(->> (d/datoms db :aevt :entry/uuid)
(pmap #(->> %
:e
(eid->entry db))))
我使用 pmap 而不是 map 并使用 :eavt
索引来获取实体的所有属性和值,而不是直接使用 d/entity
访问字段
我需要对从 Datomic 获得的实体应用额外的逻辑(如映射、条件、聚合)。我很难将它转换为 Datomic 查询(我不确定在我的情况下是否可行),这就是为什么我改用 datomic 的原始索引访问,所以大部分工作和逻辑都是在 Clojure 中完成的。
在我达到约 500K 个条目之前,它工作正常,整个方法变得非常慢。 相关代码:
(defn e->entry
"Map e into entry"
[e]
{:id (:entry/uuid e)
;; each flat field increases mapping time (seems linearly)
:date (:entry/date e)
:summ (:entry/summ e)
;; although when using nested fields, mapping time rises significantly
:groups (map #(-> % :dimension/group :group/name)
(:entry/dimensions e))})
;; query code:
(->> (d/datoms db :aevt :entry/uuid)
(map #(->> %
:e
(d/entity db)
e->entry))))
;; TODO: other actions on mapped entries ...
它需要大约 30 秒 到 运行 查询代码来映射实体,我在查询中需要的字段越多,所需的时间就越多。
这是预期的行为吗?有什么方法可以加快速度,或者我是否遗漏了什么,这是不好的方法?
要完整回答此问题需要更多信息,请随时 ask on the forum or open a support ticket。
我最终进行了以下优化,以防有人需要它:
(defn eid->entry
"Mapping via :eavt index"
[db eid]
(->> (d/datoms db :eavt eid) ; access all datoms by eid once
(seq)
(reduce (fn [m dtm]
(let [attr-key (d/ident db (:a dtm))
v (:v dtm)]
(assoc m attr-key v))))))
;; new query code
(->> (d/datoms db :aevt :entry/uuid)
(pmap #(->> %
:e
(eid->entry db))))
我使用 pmap 而不是 map 并使用 :eavt
索引来获取实体的所有属性和值,而不是直接使用 d/entity