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

时间:2016-04-03 17:09:35

标签: arangodb

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

我有3个收藏品:

TactiveService(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相同的问题)。

欢迎这种缓慢的原因的想法。

2 个答案:

答案 0 :(得分:3)

我们非常清楚GRAPH_EDGES不适合在查询中使用。

因此,我们引入了AQL pattern matching traversals,这应该会有更好的表现。

您可以像这样制定您的查询,将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,因为我们从OUTBOUND开始查询service个边缘,因此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调用会减少索引查找次数。

正如您已经注意到并使用第二个查询制定的,如果您的实际问题更适合classic join ArangoDB,您可以自由选择使用您的数据。

编辑:迈克尔是对的,方向必须是OUTBOUND

答案 1 :(得分:3)

如果出于某种原因你不想像@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替换start示例,它将只收集此特定顶点的边。 现在你也只对一个方向(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中更快,我也建议切换到最新版本。