首页 文章

Datomic的递归Datalog查询确实很慢

提问于
浏览
2

我目前正在评估Datomic的存储和查询形成本体的解析符号的用例 . 总共有225122个符号(实体)在数据库中(因此它是一个相当大的本体,但对于数据库来说不应该是一个大问题) .

结构非常标准,符号有

  • 包含它们的父符号(如子符号等)

  • supersymbols(他们继承的符号)

为了能够很好地访问这些符号,我们为每个符号都有一个唯一的 name . 这相当于以下Datomic架构:

[{:db/ident :ml/name,
  :db/valueType :db.type/string,
  :db/cardinality :db.cardinality/one,
  :db/unique :db.unique/identity}
 {:db/ident :ml/parent,
  :db/valueType :db.type/ref,
  :db/index true,
  :db/cardinality :db.cardinality/one}
 {:db/ident :ml/superclass,
  :db/valueType :db.type/ref,
  :db/index true,
  :db/cardinality :db.cardinality/one}]

现在我有了最基本的递归查询“给我所有符号(传递)包含在符号 p 中的符号” . 在Datomic术语中:

(def rules
  '[
    [(ubersymbol ?c ?p) (?c :ml/parent ?p)]
    [(ubersymbol ?c ?p) (?c :ml/parent ?c1) (ubersymbol ?c1 ?p) ]
    ])
(q '[:find ?c ?n :in $ % :where
     (ubersymbol ?c ?d) [?d :ml/name "name of a root symbol"] [?c :ml/name ?n]]
   current-db rules)

查询本身(所以中等大小的符号)需要在 55.5 秒之间,并返回80次点击 . Not milliseconds, but real seconds . 这只是我想要询问的关于数据集的最基本的查询(它旨在从Web工具中使用,以帮助建模者理解本体的结构) .

我正在运行 datomic-pro-0.9.5554 ,带有内存数据库并使用对等库(我按照"getting started"指南中的说明启动了服务器 .

非常感谢帮助为Datomic提供案例 .

马库斯

1 回答

  • 4

    编辑

    正如 fricke 自己发现的那样,这是子句排序的问题,但在查询中,而不是在规则集中 . 更有效的版本是:

    [:find ?c ?n :in $ % :where
       [?d :ml/name "name of a root symbol"]
       (ubersymbol ?c ?d) 
       [?c :ml/name ?n]]
    

    以上查询可以通过以下方式进一步改进:

    • 使用查询参数而不是在查询正文中使用动态参数

    • 使用查找引用按 :ml/name 解析输入实体

    产量:

    (d/q
      '[:find ?c ?n :in % $ ?d :where
        (ubersymbol ?c ?d)
        [?c :ml/name ?n]]
      rules current-db [:ml/name "name of a root symbol"])
    

    我的理论是,您的规则不是以Datalog可以针对此读取模式进行优化的方式编写的 - 可能导致遍历所有实体 . 我建议将它们改写如下:

    [[(ubersymbol ?c ?p) 
      (?c :ml/parent ?p)]
     [(ubersymbol ?c ?p) 
      ;; we bind a child of the ancestor, instead of a parent of the descendant
      (?c1 :ml/parent ?p)
      (ubersymbol ?c ?c1)]]
    

    这种编写规则集的方法经过优化,可以找到某个节点的后代 . 您最初编写它的方式经过优化,可以找到某个节点的祖先 .

    使用Datomic 0.9.5385在50000个实体的 balancer 二叉树上对我的机器进行快速基准测试表明,您可以通过第二种方法获得所需的性能 .

相关问题