go语句查询计划有个问题

我看go语句的查询计划,GetNeighhbor获得DstVID,GetVert根据这些ID取出Tag属性,但是这之后为什么还要跟前一步的DstVid进行一次leftjoin,想不通,GetVert不是已经根据前一步的DstVid来找的吗,这一步不是多余的吗

你的执行语句是啥?

GO FROM “player101” OVER follow WHERE properties($$).age >= 35 YIELD properties($$).name AS Teammate, properties($$).age AS Age
您好,就是很简单的示例语句

应该是dst要和edge进行join。

具体可以看代码:GoPlanner.cpp

您好,我的意思是这一步没有实际意义,可以省略掉这一步,因为dst本身就是通过edge里面的终点dst找出来的,那么没必要再进行一次join吧,这一步是多余的

这里有个 LeftJoin 的原因是要还原 GetNeighbors 的返回结果行数。LeftJoin 右侧子计划做的事情是从存储拿终点(指定终点 id)的属性,为了降低 RPC 的开销给 storaged 服务发请求之前会对这批终点 id 做去重(截图中 GetVertices 里边有个 dedup 标记),这意味着 GetVertices 返回的结果行数可能是小于 GetNeighbors 的。
所以,这个 LeftJoin 还是去不掉,去掉之后 go 语句的性能可能会变差很多。但是这里还是有一些优化空间,比如一个优化的方案是把 left join 的行为封装在 GetVertices 算子内部,修改后的执行计划大概长这样:
...->GetNeighbors->GetVertices->...
这样改有两个好处,首先是在不影响实现语义的前提下执行计划可读性变好了,其次是解决了 LeftJoin 执行依赖和数据依赖不一致的问题,可能会对一些优化规则(比如 filter 下推)更友好一点,预期会带来一些性能收益。

1 个赞

您好,感谢您的耐心解答,我还是有一点不太明白,GetVertices返回的结果行数小于GetNeighbors的结果行数,这个不是正确的吗,因为GetNeighbors找重复了,而语句的预期结果不是应该就是不重复的吗,还是在设计上这个语句的查询结果就是会保留重复呀

1 个赞

不是的。
比如, “a”-[:E1]->“b”, “a”-[:E2]->“b”, go from “a” over * yield id($$) ,这个返回两行 “b”,但 GetVertices 只会返回一行。

2 个赞

嗯嗯,我明白了,谢谢

嗯嗯,我明白了,谢谢您

好滴。欢迎给我们贡献 pr 噢!

2 个赞

如果你觉得 kyle 的回复解决了你的问题,可以勾选为解决方案的哈~