1

在测试中,我们的 Foxx 应用程序遇到了“检测到死锁”的问题。这些似乎是由遍历查询引起的。Apriori,即使不是不可能,也很难知道在遍历期间将使用哪些表。但是,我确实采用了一种特定情况,我可以确定表的数量并将 AQL 包装在事务中以进行测试:

var result = db._executeTransaction({ "collections" : { "read" : [ "pmlibrary", "pmvartype", "pmvariant", "pmproject", "pmsite", "pmpath", "pmattic" ] }, "action " : "function(){var db=require(\"@arangodb\").db;var res=db._query(\"FOR o IN ['pmlibrary/199340787'] FOR v,e,p IN 0. .7 INBOUND o pm_child RETURN p.vertices\");return res.toArray()}" });

仅供参考,集合中的表列表不包括边缘表。

然而,这种说法的僵局仍在继续。我不确定下一步该尝试什么。谢谢。

4

2 回答 2

1

我不是 ArangoDB 的索引/性能专家,但我最近也遇到了一些死锁问题,通过重构和重塑查询获得了巨大的性能提升,有时查询需要 120 秒然后需要 0.2 秒。

我做的一件关键事情是尝试帮助 ArangoDB 知道何时使用索引,并确保该索引可用。

在您的示例查询中,存在阻止 ArangoDB 知道索引发生的问题:

FOR o IN ['pmlibrary/199340787'] 
FOR v,e,p IN 0..7 INBOUND o pm_child 
  RETURN p.vertices

这样做的关键问题是您的原始 FOR 循环正在使用数组中的值,这可能会阻碍 ArangoDB 识别索引。您可以轻松地将您的 o 替换为参数,并'pmlibrary/199340787'直接输入您的值,并使用“解释”按钮查看它是否识别它可以使用索引。

我发现的一个问题是试图让使用索引变得超级清晰,这有时意味着添加额外LET的命令以允许 ArangoDB 构建数组的内容,然后它似乎知道更好地使用哪个索引。

如果您要测试上述查询的性能,而不是类似:

LET my_targets = (FOR o IN pmlibrary FILTER o._key == '199340787' RETURN o._id)

FOR o IN my_targets
FOR v,e,p IN 0..7 INBOUND o._id pm_child 
  RETURN p.vertices

这可能看起来违反直觉,但通过测试,我发现通过将查询分开以帮助 ArangoDB 注意到它可以使用索引,从而获得了惊人的性能提升。

如果有任何查询针对数组中的值,或者您使用的是动态属性名称,那么即使存在索引,它也不会总是使用索引。

我还发现服务器会缓存查询的响应,所以如果你想测试对长时间运行的查询的更改并想避免第二次 + 查询的缓存命中,我不得不停止并重新启动 arangodb3 服务。

我希望这有助于为您提供一个目标,让您可以围绕查询进行改组以使用索引。

请记住,您已经在 _id、_key、_from、_to 上具有内置索引,因此您需要尝试并确保它将使用其他有助于加快查询速度的索引。

于 2017-04-10T07:49:26.260 回答
1

正确的解决方案是使用 WITH 子句而不是事务。

于 2017-04-11T15:24:32.387 回答