[英]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.