数据原子查询性能改进

2024-03-03

我在 Datomic 数据库中有一个与此类似的架构:

; --- 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}     

随着时间的推移,任务相当静态,但每个任务平均每 5 分钟就会添加和删除一次子任务。我想说,在任何给定时间,每个任务平均有大约 40 个子任务,其中包含(几乎总是,但也有一些例外)一个参与者。我使用 Datomic 的唯一目的是能够了解任务如何随时间演变,即我想了解任务在给定时间的情况。为了实现这一目标,我目前正在做类似的事情:

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

不幸的是,这非常慢。如果租户有许多任务(例如 20 个),每个任务包含大约 40 个子任务,则从该函数返回可能需要近 60 秒的时间。我在这里做明显错误的事情吗?有可能加快这个速度吗?

更新: 整个数据集大约为 2 Gb,对等方有 3.5 Gb 内存(但如果我将其减少到 1.5 Gb,似乎没有任何区别),而交易者有 1 Gb 内存。我正在使用 Datomic 免费版。


在开始分析等之前,您可以替换

[:find ?taskIds ...]

by

[:find (pull ?task-entity [*]) ...]

减少到对等点的往返次数,从而消除了 map 语句task-entities。在第二步中替换[*]使用您真正想要为每个实体提取的适当的密钥集。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据原子查询性能改进 的相关文章

  • Clojure 是否有命名私有函数的约定?

    当我在 Clojure 中定义私有函数时 我通常使用 前缀作为视觉指示符 表明该函数不能在我的命名空间之外使用 例如 defn name let formatter formatter yyyy MM dd HH mm ss SSSS fo
  • Clojure 中使用 clj-http 进行基本身份验证

    我们正在使用clj http https github com dakrone clj http进行 HTTP 基本身份验证 我想发送带有此标头的请求 Authorization Basic dXNlcm5hbWU6cGFzc3dvcmQ
  • Java 互操作——Netty + Clojure

    我正在尝试通过 clojure 使用 netty 我可以启动服务器 但是它无法初始化接受的套接字 下面分别是错误消息和代码 有谁知道什么是 或可能是错误的 我相信问题在于 Channels pipeline server handler T
  • Clojure 测试:测试断言的否定

    这对我有用 is thrown AbstractMethodError fun obj 1 但这却炸了 is not thrown AbstractMethodError fun obj 1 出现以下错误 java lang Runtime
  • 重新创建一棵扁平的树

    我有一个地图向量 我想以嵌套方式对其进行转换 数据结构如下 def data id 1 name a parent 0 id 2 name b parent 0 id 3 name c parent 0 id 4 name a 1 pare
  • 懒惰的 juxt 函数有什么优点吗?

    在回答中一个问题 https stackoverflow com questions 10044254 is there a reverse map function关于一个使用相同参数映射多个函数的函数 A juxt 我想出了一个基本上采
  • clojure 中的反转哈希映射

    我在 clojure 中有哈希映射 key1 value1 key2 value2 key3 value1 我需要将其转换为哈希映射 value1 key1 key3 value2 key2 有 Clojure 方法可以做到这一点吗 clo
  • 在环形应用程序中捕获异常的惯用方法

    处理环形应用程序中的异常的惯用方法是什么 我想捕获异常并返回 500 页 我怎么做 我在下面的代码中使用了 Mustache 但是它不起作用 def my app try app wrap logger true wrap keyword
  • 如何在 Clojure 中更新原子的向量元素?

    我有一个矢量原子 我想更新一个本身就是地图的条目 def vector atom atom swap vector atom conj id 1 name myname 我该如何只更新该成员 在可变的 Java 领域的思维方式中 我会做这样
  • Clojure 函数 - 返回最后一条语句之前计算的值

    我有一些用 Clojure 编写的测试 这是一个简单的例子 defn test1 start server run pvt and expect PVT 0 stop server 我想返回 run pvt and expect 的结果 但
  • 什么时候应该在 Clojure 中使用临时重新绑定特殊变量这一习惯用法?

    我注意到一些库 例如 clojure twitter 使用特殊的变量 用于动态绑定的变量 被星号包围 进行 oauth 身份验证 您将身份验证保存在 var 中 然后使用 with oauth myauth 我认为这是解决此类问题的一个非常
  • core.async不是违背Clo​​jure原则吗?

    我看到许多 Clo jure 程序员对新的 core async 库充满热情 尽管它看起来很有趣 但我很难看出它如何符合 Clojure 原则 所以我有以下问题 它在任何地方都使用可变状态 正如函数名称通过感叹号所暗示的那样 例如 alt
  • 适用于具有不同数量数据字段的用户的功能

    这个问题是我练习的时候产生的教程中的观察者主题 http mishadoff com blog clojure design patterns episode 10 observer我试图将该功能应用于用户 但无法使用用户的数据字段 例如姓
  • Clojure 中 with-local-vars 和 with-bounds 之间的区别

    Clojure 的文档with local vars http clojuredocs org clojure core clojure core with local vars and with bindings http clojure
  • Clojure读行函数问题

    我试图在我的 Clojure 程序中获取控制台输入 但是当它到达程序的该部分时它给我这个错误 Exception in thread main java lang ClassCastException clojure lang LineNu
  • Emacs/Swank/Paredit for Clojure 的温和教程

    我要转向 Emacs 来工作Clojure http en wikipedia org wiki Clojure Lisp 为了能够执行以下操作 我需要在 Emacs 上设置哪些信息 自动匹配 生成相应的右括号 自动缩进 Lisp Cloj
  • Leiningen 在构建可用的 uberjar 时遇到问题

    我们正在尝试与 Leiningen 一起构建我们的 Clojure 项目 我们通过执行以下操作成功创建了 uberjar 前提条件 project clj 文件列出了依赖项 main my project core在项目 clj中 core
  • 如何在 Clojure 中链接 Promise

    在 Scala 中 您可以使用map and flatMap在未来的成功结果上运行函数 val x Future Int val y Future String x map toString 有没有比以下更好的 Clojure 类似物 de
  • 使用 CounterClockwise 和 Eclipse 在 Clojure REPL 中进行评估

    我通常使用 Emacs 但受到启发再次尝试 CCW Eclipse 我有一个 Clojure 测试项目 其源文件 src user clj 包含以下内容 ns user println hi 我有一个 REPL 我从 Window gt S
  • clojure 要求语法原理

    我很难理解 因此记住 此处描述的 clojure require 语法 http clojuredocs org clojure core 1 3 0 clojure core require http clojuredocs org cl

随机推荐

  • 在 Team Foundation Server 中实际使用 Mercurial?

    我的商店使用 TFS 并且总体上对它很满意 但缺少本地存储库提交 恢复 我开始自己在本地使用 Mercurial 来帮助管理较小的更改块 然后将它们发布到 TFS 我看到 Subversion 有一个 桥接 组件 如果中央 VCS 是 Su
  • Celery 任务已收到但未执行

    我有已收到但不会执行的 Celery 任务 我正在使用 Python 2 7 和 Celery 4 0 2 我的消息代理是 Amazon SQS 这是的输出celery worker celery worker A myapp celery
  • ASP.NET Core 应用程序中project.json 中的构建选项下的preserveCompilationContext 有什么用?

    我是 ASP NET Core 新手 我试图了解 project json 中的各种选项 但无法理解其含义保留编译上下文 true在project json 中的构建选项下 据微软称文档 https learn microsoft com
  • 如何将 HSB 转换为 RGB

    我有一台德尔福XE2项目 https stackoverflow com questions 17729550 how can you change the font color using timer control改变Label01 F
  • 捏合缩放 ListView Android

    我正在尝试在 Android 上实现捏合放大列表视图 当我单击并拖动缩放的列表视图时遇到问题 首先 这是代码 public class ScaleListView extends ListView private ScaleGestureD
  • NSOrderedSet 生成的访问器中抛出异常

    在我的 Lion 应用程序上 我有这个数据模型 关系subitems inside Item 已订购 Xcode 4 1 内部版本 4B110 已为我创建了该文件Item h Item m SubItem h and SubItem h 这
  • Vue 3 Teleport 只能在 vue 之外移植吗?

    Vue 3 有一个新的 Teleport 功能 它取代了 vue 2 中的 Portal vue 插件 但是 我发现无法将组件移植到由 vue 控制的位置 在 vue 应用程序中 它仅在移植到外部 主体 其他元素 时才有效 const ap
  • Joomla 数据库 - 如何在 getQuery 中使用 LIMIT?

    我想使用 joomla 内置数据库类构建以下查询 SELECT FROM table name ORDER BY id DESC LIMIT 1 这是我到目前为止建立的查询 db JFactory getDBO query db gt ge
  • 为什么 setTimeout() 在 Chrome DevTools 下使我的调用堆栈变得混乱?

    我有一个函数 在完成后使用 setTimeout 重新排队 有人可以解释为什么 Chrome DevTools 让它看起来像是递归调用自己吗 我的理解是每次调用的调用堆栈都应该清晰 举这个非常简单的例子 第一次命中断点时 我看到 经过 3
  • Pandas:无法附加和重新分配到函数内的 DataFrame

    我想要做的是附加到一个 DataFrame 该 DataFrame 作为参数传递给函数 类似于以下代码中按函数完成的操作f df pd DataFrame data 0 1 0 1 columns a b df Out 58 a b 0 0
  • 如何删除 Django 自动生成的 ManyToMany 表中的冗余 ID 字段?

    我的班级有两节课models py file class Person person name models CharField max length 50 class Course course name models CharField
  • iPhone:检测自上次屏幕触摸以来用户不活动/空闲时间

    有没有人实现了一项功能 如果用户在一段时间内没有触摸屏幕 您会采取特定的操作 我正在努力找出最好的方法来做到这一点 UIApplication 中有这个有点相关的方法 UIApplication sharedApplication idle
  • 如何定义多重复合函数?

    有没有一种方法可以定义一个 Haskell 函数 它接受函数 某种集合 并生成单个函数 它们从右到左的组合 I tried foldr 但这只接受其结果与其参数具有相同类型的函数列表 foldr a gt a gt a gt a 所以 我可
  • 在 Amazon EC2 Windows 实例中自动挂载 EBS 卷

    有谁知道如何自动挂载弹性块存储 http aws amazon com ebs 在 Amazon 中启动 Windows 2003 实例时的 EBS 卷弹性计算云 http aws amazon com ec2 EC2 Setup 确保 E
  • 在 IntelliJ Idea 中调试时避免 Groovy/Grails 内部机制

    我正在使用 IntelliJ Idea 8 1 2 进行 Grails 开发 Groovy 的动态特性让我很难调试代码 我总是陷入 Groovy Grails 的内部 即 CachedMethod ExpandoMetaClass 等 例如
  • 不包含多个特定单词的字符串的正则表达式

    我正在尝试组合一个正则表达式来查找特定单词don t存在于字符串中 具体来说 我想知道什么时候 主干 标签 或 分支 不存在 这是针对 Subversion 预提交挂钩 基于正则表达式匹配不包含单词的字符串 https stackoverf
  • DLL 的配置文件

    我们的应用程序在运行时从应用程序的根加载我们的自定义 DLL 这些 DLL 正在实现某些接口 并通过反射执行方法 如果自定义 DLL 必须从配置文件中读取某些值 那么我们必须将这些配置设置复制到主应用程序的 app config 文件中 有
  • Scrapy Image Pipeline:如何重命名图像?

    我有一个蜘蛛可以获取数据和图像 我想用我正在获取的相应 标题 重命名图像 以下是我的代码 蜘蛛1 py from imageToFileSystemCheck items import ImagetofilesystemcheckItem
  • .cpp 文件和 .h 文件有什么区别?

    因为我已经做了 cpp文件 然后将它们传输到 h文件 我能找到的唯一区别是你不能 include cpp文件 我缺少什么区别吗 C 构建系统 编译器 不知道有什么区别 所以这都是约定之一 约定是 h文件是声明 并且 cpp文件是定义 这就是
  • 数据原子查询性能改进

    我在 Datomic 数据库中有一个与此类似的架构 tenant db id db id db part db db ident tenant guid db unique db unique identity db valueType d