ArangoDB:GRAPH_EDGES命令在小集合上非常慢(超过20秒)



我正在评估ArangoDB,我发现GRAPH_EDGES和GRAPH_VERTICES命令非常慢,在小集合上(300个顶点)。

我有3个收藏:

战术服务(300个顶点)-->TusesCommand(300个边缘)-->Tcommand(1个顶点)

使用GRAPH_EDGES,此查询需要24秒

FOR service IN TactiveService
   LET usesCommand = (
      return FIRST(GRAPH_EDGES("topvision", {}, { edgeExamples : [{_from: service._id}], edgeCollectionRestriction : "TusesCommand", includeData:true, maxDepth : 1 }))
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

对于相同的结果,此查询需要0.020秒

FOR service IN TactiveService
   LET usesCommand = (
      FOR usesCommand IN TusesCommand
         FILTER usesCommand._from == service._id
         RETURN usesCommand
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

GRAPH_EDGES在for语句中对我来说不可用(GRAPH_VERTICES也有同样的问题)。

关于这种缓慢的原因的想法是受欢迎的。

我们很清楚GRAPH_EDGES不太适合在查询中这样使用。

因此,我们引入了AQL模式匹配遍历,它应该表现得更好。

您可以这样表述查询,用遍历替换GRAPH_EDGES

FOR service IN TactiveService
LET usesCommand = (
                   FOR v, e IN 1..1 OUTBOUND service "TusesCommand"
                       FILTER e._from == service._id RETURN e
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

请注意,指定的过滤器是隐含的true,因为我们从service开始查询OUTBOUND边,所以e._from将始终等于service._id。我们没有指定GRAPH "topvision"和稍后限制我们希望在遍历中考虑的边集合,而是像您所做的那样,使用仅考虑边集合TusesCommand的匿名图查询。

因此,再简化一点,查询可能看起来像:

FOR service IN TactiveService
LET usesCommand = (
          FOR v, e IN 1..1 OUTBOUND service "TusesCommand" RETURN {v: v, e: e}
   )
RETURN { service : service, usesCommand: usesCommand} 

这可能会返回比查询更多的顶点,但只会获取一次;因此结果集可能更大,但由于删除了查询的DOCUMENT调用,索引查找的次数减少了。

正如您已经注意到的,并在第二个查询中公式化了,如果您的实际问题在经典联接中效果更好,ArangoDB将为您提供使用此类数据的自由选择。

edit:Michael肯定是对的,方向必须是OUTBOUND

如果出于某种原因,您不想像@dothebart建议的那样升级到2.8。您也可以修复旧查询。原件:

FOR service IN TactiveService
   LET usesCommand = (
      return FIRST(GRAPH_EDGES("topvision", {}, { edgeExamples : [{_from: service._id}], edgeCollectionRestriction : "TusesCommand", includeData:true, maxDepth : 1 }))
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

查询的缓慢部分是找到起点。GRAPH_EDGES的API使用第二个参数作为开始示例。{}匹配所有起点。因此,它现在首先计算所有顶点的所有出站边(这很昂贵,因为这实际上意味着对于开始集合中的每个顶点,我们收集开始集合中每个顶点的所有边)。然后用你给出的例子对所有找到的边进行后过滤(再次删除几乎所有的边)。如果将起始示例替换为起始顶点的_id,它将只收集该特定顶点的边。现在,您也只对一个方向(OUTBOUND)的边感兴趣,所以您也可以在选项中给出它(所以GRAPH_edges首先只获取_from==service_id的边)。

FOR service IN TactiveService
   LET usesCommand = (
      RETURN FIRST(GRAPH_EDGES("topvision", service._id, { edgeCollectionRestriction : "TusesCommand", includeData:true, maxDepth : 1, direction: 'outbound' }))
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command}

然而,我仍然预计@dothebart的版本在2.8中会更快,我也建议切换到最新版本。

相关内容

  • 没有找到相关文章

最新更新