关于查询优化的问题

  • nebula 版本:v3.6.0
  • 部署方式:单机
  • 安装方式:Docker
  • 是否上生产环境N
  • 硬件信息
    • 磁盘 500G HDD
    • CPU、内存信息 32C 32G
  • 问题的具体描述
    写入300W点,2999999条边,点id从1到300W,构造一棵完全二叉树,对比match查询效率。共用了四种查询语句,其中第四种查询直接把服务查挂了。
    语句一:MATCH p = (m:Process {pguid:‘2999999’})<-[r:PROCESS_CREATE0…50]-(n:Process) return p
    语句二:MATCH p = (m:Process )-[r:PROCESS_CREATE
    0…50]->(n:Process{pguid:‘2999999’}) return p
    语句三:MATCH p = (m:Process {pguid:‘2999999’})<-[r:PROCESS_CREATE0…50]-(n:Process{pguid:‘1’}) return p
    语句四:MATCH p = (m:Process {pguid:‘1’})-[r:PROCESS_CREATE
    0…50]->(n:Process{pguid:‘2999999’}) return p

对于后两种语句三和语句四应该是没有做进一步的优化,貌似是选择左边的过滤条件为起始点,如果有多个过滤条件,这里是否考虑根据指定节点的出入度选择出入度少的节点作为起始节点查询。

执行计划调优可以参考 @wey 的这片文章 nGQL 简明教程 vol.02 执行计划详解与调优

看下执行计划,如果属性索引被正确选到那应该也没有太多优化的可能。

这个配置项你可以试一下:max_edge_returned_per_vertex,会避免中间拓展过程中超级节点的影响,但是不一定保证正确性。

1 个赞

构建的是一棵完全二叉树,不存在稠密节点,这个主要是涉及到遍历顺序的问题,这里分别指定了顶点和叶子节点两个条件,如果是自底向上遍历,只有一条路径就很快;但是如果是自顶向下遍历,就需要加载很多数据都计算节点了。所以我想说的是,如果有多个过滤条件,是否可以先判断多个过滤点的出入度,选择出入度小的为起始点遍历,而不是从左到右选第一个。

1.您构造的“完全二叉树”中,您所说的判断”出入度“是可以起到优化的效果。但这并不是一种通用的优化思路。我想完全可以构造出反例:如点A只连接了点B,而点B连接了全图其他所有点的情况,这种情况下选择A做起点就可能导致全图的遍历。
2.我想出入度可能是判断后续图遍历规模的一个可参考指标,但是并不能草率的判定。
3.nebula内部并没有存储点的出入度信息,想要获取的话需要对边进行计数。这也会消耗额外的时间。

2 个赞

需要计算出入度确实也是一个问题,对于这种情况,双向bfs或许也是一种解决办法

我们的找路径的函数就是用的双向bfs