簡體   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