Fetch prop on * 查询顶点详情(不指定具体顶点类型)性能问题

  • nebula 版本:2.6.2

  • 部署方式:分布式 ,replica=3,partition_num=15

  • 硬件信息 :3台4核cpu、16G内存、256G ssd

  • 问题的具体描述:
    *当使用Fetch prop on 语法查询顶点详情,但不指定具体顶点类型时,查询性能会随着namespace下tag类型数量的增多越来越差,查询耗时和namespace下tag类型数量近似线性相关
    一般来说,为了更好的查询性能,使用Fetch语法的时候会尽可能指定tag的类型,但是部分场景可能并不清楚具体的tag类型是什么,所以只能使用Fetch *的语法。比如说,要查询与某个顶点相关联的所有顶点,由于查询前不清楚这个顶点具体关联了哪些类型,ngql语句一般会这么写:
    go from “vid” over * yield dst(edge) as dst | fetch prop on * $-.dst
    所以在这种场景下似乎不得不使用fetch *语法来实现功能:

     下面来简单对比namespace下不同tag类型数量对Fetch *语法的性能影响:
     首先当namespace下只有100个tag类型时查询10000个顶点耗时1.97s
    


    当namespace下tag类型数量增加到1000个时,查询10000个顶点耗时19.79s,耗时竟然达到前面的10倍!

    另外如果使用Fetch语法时指定了tag类型的话,性能就非常快,不受namespace下tag类型数量的影响,查询10000个顶点仅耗时0.22s

     nebula中目前点的存储格式如下所示:
    


    即使在不指定tagID的情况下,应该也能够通过Type+PartID+VertexID来前缀搜索得到对应的点,而且我们系统中一个vid只会对应一个tag类型的点,应该也不可能导致查询耗时会随着tag类型数量的增多而线性增长的。
    通过profile命令可以看到Fetch prop on *语句执行过程中,getVertices步骤会获取当前namespace下的所有tag类型定义,返回结果之前,代码应该会通过TagID找到对应的tag定义,然后解析value值得到最终的结果。是不是这一步实现有些问题,导致Fetch *语法的查询耗时会随着tag类型增多而线性增长?
    如果确实是这块存在问题,是否能够通过优化代码解决?

我们也遇到了相同的问题,请问这边可以优化吗?

稍等哈,我们研发等会帮你看看哈 cc @yuanlu

谢谢!

你好,关于该性能问题,我们高度重视,已经在 代码库中提了一个issue,https://github.com/vesoft-inc/nebula/issues/4301 ,后续会有开发定位和改进。

好的,谢谢啦~

每个tag类型都会在storaged端生成一个tagnode,每个tagnode都会对vid拿一次数据,所以tag类型越多,需要磁盘查询的次数越多,而且如果大多数tag都没数据的情况下,缓存miss,查磁盘,然后都miss,甚至可能要查多次磁盘,速度慢正常的,当然,如果所有index block都在内存会快一点,应该不用查磁盘 :thinking:看看大佬们有什么解决方法

由于你不知道顶点关联了哪些类型,所以只能所有类型都查一遍;而一个顶点只对应一个类型是业务强相关的,实际上一个顶点支持对应很多个类型。所以查询的时候,每个(类型+顶点)的组合都会查一遍。这么看查询耗时随着tag类型增多而线性增长还是挺合理的 :rofl:

按nebula目前的存储格式,Type+PartID+VertexID+TagID应该是能够精确定位到一个点的,但使用fetch *无法指定Tag类型的情况下,是不是可以考虑通过前缀搜索Type+PartID+VertexID来定位具体的点,定位到相关点之后,就能拿到TagID的值了,这样是不是就可以避免把所有(类型+顶点)的组合都查询一遍了?如果每次根据vid获取详情都要把所有(类型+顶点)的组合查询一遍,tag类型多些的时候,查询实在是太慢了 :joy:

你说的对,加个新的node和plan就好了,看看官方怎么改吧 :+1:t2:

1 个赞

目前企业版通过cache不存在的tag key改善了这个问题,当然添加新storage access接口也是可以考虑的,可以关注这个issue,Query optimization summary based on cache experiment · Issue #4063 · vesoft-inc/nebula · GitHub

2 个赞

嗯,我理解缓存不存在的tag key只能缓解这个问题,希望后续能在storage中加一个通过前缀匹配来获取不指定tag类型的点的接口吧,这样才能从根本上解决这个问题

1 个赞

此话题已在最后回复的 30 天后被自动关闭。不再允许新回复。

浙ICP备20010487号