我一直在开发一个使用arangodb的配置管理系统,它收集一些常用软件的配置数据,并将其传输到一个程序中,该程序将根据一些预定义的规则生成这些软件之间的关系,然后将这些关系保存到arangodb中。关系建立后,我提供了查询数据的API。一个重要的查询是生成这些软件的拓扑。我使用图遍历来生成具有以下AQL的拓扑:
for n in nginx for v,e,p in 0..4 outbound n forward, dispatch, route,INBOUND deployto, referto,monitoron filter @domain in p.edges[0].server_name return {id: v._id, type: v.ci_type}它可以生成以下拓扑:software relation topology
看起来挺好的。然而,大约需要10秒才能完成查询,这是不可接受的,因为数据量不是很大。我检查了所有的集合和最大的集合,"forward“边缘集合只有大约28000个文档。所以我做了一些测试:我把深度从0..4改为0..2,只用了0.3秒就完成了查询我把深度从0..4改成了0..3,0..4大约需要3秒,因为在“前进”边缘有一个server_name属性,所以需要大约10秒,所以我添加了一个散列索引(server_name*),但是似乎arangodb没有使用explain execute plan中的索引,有什么提示我可以优化查询吗?为什么在这种情况下不能使用索引?
希望有人能帮我解决这个问题。提前谢谢你,
发布于 2017-01-20 18:07:23
首先,我已经尝试了您的查询,我可以看到,出于某种原因:
filter @domain in p.edges[0].server_name未正确优化。这似乎是一个内部问题,优化规则不够好,我将对此进行详细研究,并尝试确保它如预期的那样工作。由于这个原因,它还不能在这种情况下使用不同的索引,并且不会在级别1上正确中止搜索的短路。我很抱歉给您带来不便,因为您做的方式应该是正确的。
现在要快速解决这个问题,您可以将查询的第一部分拆分成单独的步骤:
这是我修改过的查询的快速版本(不包括nginx,请参阅较慢的版本)
FOR n IN nginx
FOR forwarded, e IN 1 OUTBOUND forward
FILTER @domain IN e.server_name
/* At this point we only have the relevant first depth vertices*/
FOR v IN 0..3 OUTBOUND forward, dispatch, route, INBOUND deployto, referto, monitoron
RETURN {id: v._id, type: v.ci_type}这是我修改过的查询的一个稍微慢一点的版本(保存你的输出格式,我认为它会比你正在使用的那个更快)
FOR tmp IN(
FOR n IN nginx
FOR forwarded, e IN 1 OUTBOUND forward
FILTER @domain IN e.server_name
/* At this point we only have the relevant first depth vertices*/
RETURN APPEND([{id: n._id, type: n.ci_type}],(
FOR v IN 0..3 OUTBOUND forward, dispatch, route, INBOUND deployto, referto, monitoron
RETURN {id: v._id, type: v.ci_type}
)
)[**]
RETURN tmp在这里,我可以给出一些一般性的建议:
for n in nginx for v,e,p in 0..4出站n转发,调度,路由,入站部署,参考,监控选项{bfs: true,uniqueVertices:"global"} filter @ p.edges.server_name in p.edges.server_name返回{id: v._id,类型: v.ci_type}
我所做的改变是我在遍历中添加了选项: bfs: true =>意味着我们进行广度优先搜索,而不是深度优先搜索,我们只需要这样做就可以使结果具有确定性,并确保路径为4的所有顶点都将被正确到达uniqueVertices:“=>”全局意味着只要在一次遍历中发现一个顶点(所以在您的例子中,每个nginx都是单独的),它就会被标记,不会再被查看。
如果您还需要所有不同边缘的列表,则应该使用uniqueEdges: "global"而不是uniqueVertices: "global",这将在边缘级别进行唯一性检查。
https://stackoverflow.com/questions/41735589
复制相似问题