当前位置 : 主页 > 网络安全 > 测试自动化 >

neo4j – 如何解释Cypher的LOAD CSV子句的性能?

来源:互联网 收集:自由互联 发布时间:2021-06-22
我在Neo4J 2.1.2中使用Cypher的LOAD CSV语法.到目前为止,它是对以前版本中所需的更多手动ETL过程的巨大改进.但是我在一个案例中遇到了一些不符合我期望的行为,我想知道我是否遗漏了一些
我在Neo4J 2.1.2中使用Cypher的LOAD CSV语法.到目前为止,它是对以前版本中所需的更多手动ETL过程的巨大改进.但是我在一个案例中遇到了一些不符合我期望的行为,我想知道我是否遗漏了一些东西.

正在使用的密码查询是这样的:

USING PERIODIC COMMIT 500
LOAD CSV FROM 'file:///Users/James/Desktop/import/dependency_sets_short.csv' AS row
MATCH (s:Sense {uid: toInt(row[4])})
MERGE (ds:DependencySet {label: row[2]}) ON CREATE SET ds.optional=(row[3] = 't')
CREATE (s)-[:has]->(ds)

以下是CSV的几行:

227303,1,TO-PURPOSE-NOMINAL,t,73830
334471,1,AT-LOCATION,t,92048
334470,1,AT-TIME,t,92048
334469,1,ON-LOCATION,t,92048
227302,1,TO-PURPOSE-INFINITIVE,t,73830
116008,1,TO-LOCATION,t,68204
116007,1,IN-LOCATION,t,68204
227301,1,TO-LOCATION,t,73830
334468,1,ON-DATE,t,92048
116006,1,AT-LOCATION,t,68204
334467,1,WITH-ASSOCIATE,t,92048

基本上,我根据它的ID值(第五列)匹配一个Sense节点(先前已导入).然后我正在进行合并以获得DependencySet节点(如果存在),或者创建它.最后,我在Sense节点和DependencySet节点之间创建了一个has边缘.到目前为止一切顺利,这一切都按预期工作.随着CSV大小的增长,性能令人困惑.

CSV Lines       Time (msec)
------------------------------
500             480
1000            717
2000            1110
5000            1521
10000           2111
50000           4794
100000          5907
200000          12302
300000          35494
400000          Java heap space error

我的期望是增长会或多或少是线性的,特别是当我按照manual推荐的每500行提交时,但它实际上更接近于多项式:

更糟糕的是,在300k到400k行之间,它会遇到Java堆空间错误.根据之前进口的趋势,我预计400k的进口需要一分多钟.相反,它会在遇到堆空间错误之前搅拌大约5-7分钟.看起来我可以将这个文件分成300,000行的块,但这不是“使用周期性委托”应该做的,或多或少?我想我也可以为Neo4J提供更多内存,但同样,我不清楚为什么我应该在这种情况下.

另外,要明确的是,Sense.uid和DependencySet.label上的查找都会被编入索引,因此这些查找的查找代价应该非常小.这是架构的一个片段:

Indexes
  ON :DependencySet(label) ONLINE (for uniqueness constraint)
  ON :Sense(uid)           ONLINE (for uniqueness constraint)

对于替代方法的任何解释或想法将不胜感激.

编辑:问题肯定似乎是在查询的MATCH和/或CREATE部分.如果我从Cypher查询中删除第3行和第5行,它就可以正常运行.

我假设您在运行此LOAD CSV导入之前已经创建了所有Sense标记的节点.我认为正在进行的是,当您将带有标签Sense的节点匹配到内存中并通过CREATE(s) – [:HAS] – >(ds)创建从DependencySet到Sense节点的关系时,您将提高可用的堆.

另一种可能性是需要增加内存映射设置中关系存储的大小.在您的场景中,看起来Sense节点与图中的其他节点具有高度的连接性.发生这种情况时,这些节点的关系存储需要更多内存.最终当你达到400k节点时,堆最大化了.到那时为止,它需要进行更多垃圾收集并从磁盘读取.

Michael Hunger撰写了一篇关于内存映射设置的优秀博客文章,以实现快速LOAD CSV性能.见:http://jexp.de/blog/2014/06/load-csv-into-neo4j-quickly-and-successfully/

那应该可以解决你的问题.我没有看到您的查询有任何问题.

网友评论