繁体   English   中英

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

[英]ArangoDB: GRAPH_EDGES command very slow (more than 20 sec) on small collections

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

我有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相同的问题)。

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

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

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

您可以这样GRAPH_EDGES查询,将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} 

请注意,由于我们查询了从service开始的OUTBOUND边,因此指定的过滤器隐式为true ,因此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可让您自由选择使用这样的数据。

编辑 :迈克尔肯定是正确的,方向必须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使用第二个参数作为开始示例。 {}匹配所有起始点。 因此,它现在首先计算所有顶点的所有出站边缘(这很昂贵,因为这实际上意味着对于start集合中的每个顶点,我们收集start集合中每个顶点的所有边缘)。 然后用您提供的示例对所有找到的边缘进行过滤(这将再次去除几乎所有的边缘)。 如果将起始示例替换为起始顶点的_id,它将仅收集该特定顶点的边。 现在您也只对一个方向的边缘感兴趣(出界),因此也可以在选项中给出它(因此,只有_from == service._id的边缘才被GRAPH_EDGES提取)。

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中更快,我也建议切换到最新版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM