NebulaGraph源码优化--NGQL查询过滤下推

总结:NGQL查询,一度一度扩散的多跳查询,GetNeighbors的Filter都已下推到存储层

一、NGQL每跳一步Filter下推优化

1.下一跳仅依赖上一跳的ID,去掉InnerJoin

profile go from 'player101' over follow yield follow._dst as fid | go from $-.fid over serve yield serve._dst as tid;

优化前:
在这里插入图片描述
优化后:
在这里插入图片描述

2.存在InnerJoin的常量Filter下推到存储层

profile go from 'player101' over follow yield follow._dst as fid | go from $-.fid over follow where follow.degree>70  yield follow._dst as tid;

优化前:
在这里插入图片描述
优化后:
在这里插入图片描述

3.存在InnerJoin的变量($-.)Filter下推到存储层

profile go from 'player101' over follow yield follow._dst as fid, follow.degree as num | go from $-.fid over follow where follow.degree<$-.num  and follow.degree>70 yield follow._dst as tid;

优化前:
在这里插入图片描述
优化后:
在这里插入图片描述

4.存在LeftJoin的Filter下推到存储层

profile go from 'player101' over follow where follow.degree>90 and $$.player.age>35 yield follow._dst as fid, follow.degree;

优化前:
在这里插入图片描述
优化后:
在这里插入图片描述

二、NGQL语法{ SAMPLE <sample_list> | <limit_by_list_clause> }中,添加FLATSAMPLE <sample_list>语法

	FLATSAMPLE意为拍平ids,每个id取样<sample_list>个

在这里插入图片描述

源码改动

NGQL下推部分源码改动主要涉及到两方面:存储层FilterNode支持变量过滤;引擎层执行计划GoPlanner构建GetNeighbors时,进行Filter的判断、剪枝和变量下推

1.存储层改造

存储层变量下推支持源码改造

	Graphd变量封装在req中传到存储层,存储层遍历buildPlan的存储层执行计划,将变量放到FilterNode中。
	
	当Filter迭代器执行到check时,filterExp_是InputExpressionh会用传过来的数据进行过滤。

2.引擎层改造

剪枝和变量下推入口

	构建GetNeighbors执行计划中,如果存在filter,剪枝放入GetNeighbors的filter中;判断filter是否有
	InputExpression,有就把变量传到存储层。

剪枝及变量下推判断逻辑

	剪枝的逻辑:
	1. kDstProperty类型的过滤条件裁掉;
	2. 若裁掉的条件父节点为逻辑OR(kLogicalOr),剪掉整个OR;
	3. 若裁掉的条件父节点为逻辑AND(kLogicalAnd),剪掉当前分支。

	剪枝部分可以看成一道二叉树的算法题:
	一颗完全二叉树共存在四类节点,非叶子节点包括OR和AND,叶子节点包括普通节点和DST节点。
	DST节点直接剪掉;OR节点下存在剪枝,则剪掉整个OR;AND节点下子节点存在剪枝,保留未被剪掉的分支。如图:

Filter下推剪枝

在这里插入图片描述

	执行器部分,如果需要变量下推,则在构建Vid的DataSet中,加入其他变量。

问题、可优化和性能提升

1.问题

	在未优化前,业务中会出现超级节点。当查询到这些超级节点时,会依赖属性过滤获取部分数据,由于
	大部分情况下Filter都未能下推,导致大量数据需要加载到引擎层才能过滤,耗时长久,占据大量资源导
	致数据库整体性能受到影响;后面采用 limit [1000] 这种方式强行限制存储层的数据量,但是Filter要在
	引擎层才能做,导致传输回来的1000条数据中很少有符合条件的;limit的数量过多,又会出现一开始的
	问题。因此,Filter必须要在存储层做才能支持业务场景,提升数据库性能。

2.可优化

	当前改造的源码,只是能做到Filter下推,整体上还很粗略。
	
	1. 当前只做了GetNeighbors的Filter下推,GetVertices也是可以做的
	2. 正常逻辑来说,下推应该再优化执行计划阶段做,但由于很多情况很难考虑全面,实现难度会增大很多,所以把这部分放到构建阶段
	3. 未改变整体的执行计划,这就会导致在GetNeighbors Filter过的数据,还是会经过引擎层的Filter,增加耗时,后续执行计划可以尝试精简合并下

3.性能提升

	性能提升方面没办法找一个通用的标准。以我们的一个业务来说,由于本身就是多跳查询,当再遇到
	较大节点或者超级节点的话,优化前可能需要3-5s的查询时间,优化后基本能在300ms-500ms的范围;
	正常查询节点优化前基本在300ms左右,优化后基本能控制在200ms内。查询性能优化,最根本的解决
	办法还是建模时尽量减少超级节点的形成,但数据的不可控性使我们很难做到,所以只能提高对数据库的要求。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值