将一个neo4j语句 改为nebula 发现效率反而慢很多,附上原本查询语句,寻找查询效率最好的方式

原neo4j查询语句如下:

MATCH (intopice:intopiece) WHERE intopice.loan_business_id = "A1150420200420018765" 
         CALL apoc.path.subgraphNodes(intopice, {maxLevel:1,uniqueness:"NODE_GLOBAL"}) 
         YIELD node  where node.commit_time<intopice.commit_time with collect(node.loan_business_id) as list 
MATCH (intopice:intopiece) WHERE intopice.loan_business_id = "A1150420200420018765"
         CALL apoc.path.subgraphNodes(intopice, {maxLevel:2,uniqueness:"NODE_GLOBAL"}) 
         YIELD node  where node.commit_time<intopice.commit_time  with node as result 
         where  NOT(result.loan_business_id in list)
         and result.loan_business_id <> "A1150420200420018765"
         and result.commit_time<intopice.commit_time
         return count(result.loan_business_id) as TOTAL ,
         sum(toInt(result.loan_value)+1)/2 as LOAN,
         sum(toInt(result.overdue_value)+1)/2 as B_OVERDUE ,
         sum(toInt(result.evasion_debts)+1)/2 as B_EVASION ,
         sum(toInt(result.out_of_contact)+1)/2 as B_LOST ,
         sum(toInt(result.other_blacklist)+1)/2 as B_OTHER ,
         sum(toInt(result.online_mob1_m1)+1)/2 as OVERDUE_ONLINE_FLAG1,
         sum(toInt(result.online_mob2_m1)+1)/2 as OVERDUE_ONLINE_FLAG2,
         sum(toInt(result.online_mob6_m1)+1)/2 as OVERDUE_ONLINE_FLAG3,
         sum(toInt(result.offline_m1)+1)/2 as OVERDUE_OFFLINE_FLAG1,
         sum(toInt(result.offline_mob3m1)+1)/2 as OVERDUE_OFFLINE_FLAG2,
         sum(toInt(result.offline_mob6m2)+1)/2 as OVERDUE_OFFLINE_FLAG3,
         sum(toInt(result.edu_overdue30)+1)/2 as OVERDUE_EDU_FLAG1,
         sum(toInt(result.edu_mob3m2)+1)/2  as OVERDUE_EDU_FLAG2,
         sum(toInt(result.edu_mob6m2)+1)/2 as OVERDUE_EDU_FLAG3,
	 sum(case when result.overdue_value=1 OR result.evasion_debts=1 OR result.out_of_contact=1 OR result.other_blacklist=1 then 1 else 0 end ) as TOUCH;

这个语句在大数据量的情况下 查询二跳的数据效率非常之高,稳定几十毫秒,希望能有一个相差不大的nebula语法实现,要不然就无法替换原功能,自己尝试了很多种方法,效果很差,要不然只能不用这个技术栈了

1 个赞

在线蹲一个答案

  • 您的库是多少顶点、多少边?
  • 上面的match语句,用nebula graph执行是多长时间?

环境 物理机一台 配置 40C 256G 6600G 单机部署
顶点 1200 边类型30种,边数据量在6000W ,为了实现上面的nebula语句 我加了索引后使用了 lookup + go +munis 实现了,效果不理想。之后再论坛上请教后,使用建议的 复合match 匹配二度的方式,效果也不理想,之后就卡住了,试了好多方式,官方的资料也翻一遍了,后面我们会加查询3跳的数据,如果这个效率的话就瓦特了,我想着是不是我哪块没搞清楚,固贴出完整的语句,想看下这种需求最优解是什么样子。目前我将数据重新制作了一份,之后会贴出数据模型,预计明天可以完全导入,这之前能给出个方向就太好了。。。顺便补充下lookup+go 二跳就很慢,愁白了少年头,中年头,老年头

1 个赞

子图的过滤已经在 roadmap 里了哈

在那之前,我试试能不能写出来更好的哈,稍等

我找到了一个 mitigation,在 https://github.com/vesoft-inc/nebula/pull/4357 合并之前,你评估看下。

按照我的理解,你是要两跳子图去掉一跳子图的所有点,然后对点额属性进行处理输出,并且点上的 commit_time 按需过滤,对吧?

现在的想法是:

  • 取两跳子图,只取第二跳,第二跳里是没有第一跳的点的 (用 collect(nodes) 之后,取 index 1)
  • 再 unwind 成为列(第二跳的点),按列取属性
  • 取完了属性,过滤 commit_time

这里边有两个问题

  1. unwind 成列需要 https://github.com/vesoft-inc/nebula/pull/4456 ,这个好办,你导完数据,把二进制升级到 nightly build 可解

  2. commit_time 在这个 query中没法传递给后边,这个只能用单独的查询获得,然后再应用层穿进去,所以最终是两个查询

第一个查询,从 loan_business_id 获得 intopice 的 vid 与 commit_time

(root@nebula) [basketballplayer]> 

LOOKUP ON player WHERE player.name == "Tony Parker" \
    YIELD id(vertex) AS id, player.age AS commit_time
+-------------+-------------+
| id          | commit_time |
+-------------+-------------+
| "player101" | 36          |
+-------------+-------------+

第二个查询(前边的想法),那些sum我就不写了,age 代表 commit_time,name代表你要 sum的东西:

我们获得了 player101 和 36

GET SUBGRAPH 2 STEPS FROM "player101" IN follow YIELD VERTICES AS nodes | \
    YIELD collect($-.nodes) AS nodes | \
    UNWIND $-.nodes[1] AS n_2step | \
    YIELD id($-.n_2step) AS n | \
    FETCH PROP ON player $-.n YIELD vertex AS v | \
    YIELD $-.v.name AS name WHERE $-.v.age < 36
(root@nebula) [basketballplayer]> GET SUBGRAPH 2 STEPS FROM "player101" IN follow YIELD VERTICES AS nodes | YIELD collect($-.nodes) AS nodes | UNWIND $-.nodes[1] AS n_2step | YIELD id($-.n_2step) AS n | FETCH PROP ON player $-.n YIELD vertex AS v | YIELD $-.v.name AS name WHERE $-.v.age < 36
+---------------------+
| name                |
+---------------------+
| "Dejounte Murray"   |
| "Marco Belinelli"   |
| "LaMarcus Aldridge" |
+---------------------+
1 个赞

好的 我晚上就能得出结果 对比下 感谢大手子

1 个赞

一波三D啊,服务还起不来。。表现是meta服务报错


gradphd 报错
,0.0
,还有那个语句还没来得及尝试,那么多2跳数据下潜到fetch 再查,速度会慢吗

单起一个帖子看下起不来的问题?快速问,硬盘没满吧?
单独重启一下meta?

这个代价近似于第二跳 WITH PROP 的 GET SUBGRAPH,就是一个 GetVertices

上面说升级二进制版本,需要我使用代码编译后部署吗

不用的,无论是docker image 还是 二进制包都有每天晚上的 build

文档里下载安装的例子里就有二进制包的 nightly 版本 URL,docker 的话,改 tag 为 nightly就行(或者参考 docker compose master 的配置)

我应该是明白你意思了,但是这个nightly 版本的,可以用于生产吗?

不推荐,可以先 poc,生产还是推荐正式的版本

额,,那还有其他方式吗?只要性能好也可以,也不是说必须用子图得,大佬

具体描述下我得数据吧 只有一种节点类型,但是存在34种边关系 (银行卡,电话号这些关系)有些边数据量会达到上亿级别

浙ICP备20010487号