J'ai un schéma qui ressemble à ceci dans une base de données Datomic:améliorations Datomic de performances des requêtes
; --- tenant
{:db/id #db/id[:db.part/db]
:db/ident :tenant/guid
:db/unique :db.unique/identity
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :tenant/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :tenant/taks
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db.install/_attribute :db.part/db}
; --- task
{:db/id #db/id[:db.part/db]
:db/ident :task/guid
:db/unique :db.unique/identity
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :task/createdAt
:db/valueType :db.type/instant
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :task/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :task/subtasks
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db.install/_attribute :db.part/db}
; --- subtask
{:db/id #db/id[:db.part/db]
:db/ident :subtask/guid
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :subtask/type
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :subtask/startedAt
:db/valueType :db.type/instant
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :subtask/completedAt
:db/valueType :db.type/instant
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :subtask/participants
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db.install/_attribute :db.part/db}
; --- participant
{:db/id #db/id[:db.part/db]
:db/ident :participant/guid
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :participant/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
Les tâches sont assez statiques au fil du temps, mais les sous-tâches sont ajoutés et supprimés en moyenne environ une fois par 5 minutes par tâche . Je dirais que chaque tâche en moyenne a environ 40 sous-tâches à un moment donné contenant (presque toujours, mais il y a quelques exceptions) un participant. Mon seul objectif d'utiliser Datomic est de pouvoir voir comment les tâches ont évolué au fil du temps, c'est-à-dire que j'aimerais voir à quoi ressemblait une tâche à un moment donné. Pour atteindre je suis en train de faire quelque chose de similaire à ceci:
(defn find-tasks-by-tenant-at-time
[conn tenant-guid ^long time-epoch]
(let [db-conn (-> conn d/db (d/as-of (Date. time-epoch)))
task-ids (->> (d/q '[:find ?taskIds
:in $ ?tenantGuid
:where
[?tenantId :tenant/guid ?tenantGuid]
[?tenantId :tenant/tasks ?taskIds]]
db-conn tenant-guid)
vec flatten)
task-entities (map #(d/entity db-conn %) task-ids)
dtos (map (fn [task]
(letfn [(participant-dto [participant]
{:id (:participant/guid participant)
:name (:participant/name participant)})
(subtask-dto [subtask]
{:id (:subtask/guid subtask)
:type (:subtask/type subtask)
:participants (map participant-dto (:subtask/participants subtask))})]
{:id (:task/guid task)
:name (:task/name task)
:subtasks (map subtask-dto (:task/subtasks task))})) task-entities)]
dtos))
Malheureusement c'est extrêmement lent. Le retour de cette fonction peut prendre près de 60 secondes s'il y a beaucoup de tâches pour un locataire (disons 20) contenant chacune environ 40 sous-tâches. Est-ce que je fais quelque chose qui cloche mal ici? Est-il possible d'accélérer cela? L'ensemble de données est d'environ 2 Go et l'homologue a 3,5 Go de mémoire (mais cela ne semble pas faire de différence si je le diminue pour dire 1,5 Go) et le transcript a 1 Go de mémoire . J'utilise Datomic Free.
Il serait plus facile de vous aider si vous aviez profilé votre code pour trouver les goulots d'étranglement. Vous pouvez utiliser la bibliothèque Tufte pour cela. –
Vous pouvez obtenir de meilleurs résultats en utilisant l'API Pull plutôt que des entités (vous pouvez transformer les résultats retournés par la suite) –
@ValentinWaeselynck merci pour le conseil, je vais essayer et revenir. – Johan