图数据库批量录入大概有以下几种方法:
- Cypher 语句(create):适合1-1w节点的场景,速度很慢
- apoc.periodic.iterate 接口 + Cypher Create:(实测)速度较 Cypher 提高十几倍,百万节点导入时间超过1周,无法接受
- neo4j 自带 load csv 语句: 适合1w-10w 节点场景,速度较快(来源网络,未验证)
- apoc.load.csv:利用 apoc 优化过的 load.csv 接口,从csv 文件中间数据导入 neo4j,速度很快,优点是可以在 neo4j 运行时导入数据,(实测)导入速度在 3.5w节点/s(20vCPU+32G内存),百万级的节点导入没有问题
- apoc.periodic.iterate API + apoc.load.csv API :这两个结合起来使用,速度成几倍提高,具体提高的速度,与batch 大小设置,线程池设置,数据量有关
- Batch Inserter | Batch Import:第三方导入工具,据说适合千万级以上的节点,也是数万节点/s,没有实测,感觉应该跟 apoc.load.csv 差不多
- Neo4j import:neo4j 自研的导入工具,需要 neo4j 数据库离线,不适合日常数据导入,据说速度也是几万/s,应该比在线导入快,对csv文件格式有要求,适合第一次初始化数据
在上一篇文章 Ai解决图数据回环问题 中,使用 Cypher 语句创建关系非常快,但是在节点导入时遇到了速度非常慢的难题,通过上述的 apoc.load.csv 方式,得以解决
代码示例如下
CALL apoc.periodic.iterate("
CALL apoc.load.csv('file:///import/xxx.csv', {
delimiter: ',',
skip: 1,
mapping: {
A: {
labels: ['A'],
properties: {a_id: 'line[0]', b: 'line[1]', c: 'line[2]', d: 'line[3]', e: 'line[4]', f: 'line[5]'}
}
}
}) yield map as row return row
",'
CREATE (u:A) SET u = row
', {batchSize:10000, iterateList:true, parallel:true});
该方法从 xxx.csv 文件中读取数据,跳过第一行(第一行为表头),按照列作为节点属性(a,b,c,d,e)创建节点
batchSize
是一次处理的数据量,iterateList:true
告诉 iterate 从文件中返回的数据作为列表处理,parallel:true
告诉 iterate 按照默认的线程池大小并行的处理数据
该方法并行度高,虽然apoc 的底层也是调用 Cypher 语句,但是 load.csv 是根据导入任务进行过优化,同时提高并行度来增加导入带宽,从而大大提高导入速度