我正在开发一个项目,我需要在远程图表上执行子图的许多合并操作。子图的某些元素可能已存在于远程图中。我正在使用py2neo v3和neo4j。
我尝试使用neo4j的create
和merge
功能,并且两者都获得了令人惊讶的糟糕表现。更令人惊讶的是,合并子图的时间似乎与节点数量和关系数量呈二次方增长!当子图太大时,事务就会挂起。我应该说的一件事是我检查过并且不是py2neo会生成许多cypher语句,这些语句与子图的大小成二次方。因此,如果出现问题,可能是我使用这些技术,还是使用neo4j的实现。我也尝试查看py2neo生成的查询的查询计划,并没有找到任何答案,为什么查询时间如此显着增长,但由于我相对不启动,所以不要接受我的话。
我几乎无法在线找到任何相关信息,所以我尝试进行适当的基准测试,比较节点数量和子图拓扑功能的性能,具体取决于我是使用合并还是创建操作以及我是否使用独特的约束。我在下面列出了我对“线性”拓扑图得到的一些结果,这意味着关系数与节点数大致相同(它不会以二次方式增长)。 在我的基准测试中,我为随机分配的节点和关系使用了5种不同类型的标签,并重用了远程图中已存在的30%的节点。我创建的节点只有一个属性作为标识符,我根据是否在此属性上添加唯一约束来报告性能。所有合并操作都在一个事务中运行。
使用py2neo创建函数查询具有线性拓扑结构的图形的节点数量
使用py2neo合并函数查询具有线性拓扑结构的图形的节点数量
正如您所看到的,所花费的时间似乎与节点(和关系)的数量呈二次方增长。
我很难回答的问题是我是做错了什么,还是做了我应该做的事情,或者我们应该从neo4j那些表现出来的那种表演。无论如何,似乎我可以做的就是不要一次尝试合并大的子图,而是从批量合并节点然后关系开始。这可能并且可行,但如果有人有任何建议或见解可以分享,我想深究这一点。
以下是重现上述结果的要点列表,以及其他内容。 https://gist.github.com/alreadytaikeune/6be006f0a338502524552a9765e79af6
按照Michael Hunger的提问:
在我分享的代码中,我尝试为neo4j.bolt日志编写格式化程序,以捕获发送到服务器的查询。但是,我没有系统的方法为它们生成查询计划。
我没有没有docker的尝试,我没有SSD。但是,考虑到我为jvm分配的大小和我正在处理的图形的大小,一切都应该适合RAM。
我使用neo4j的最新docker镜像,所以相应的版本似乎是3.3.5
答案 0 :(得分:0)
不幸的是,v3中的合并例程(以及其他一些例程)有点天真,并且不能很好地扩展。我为py2neo v4计划了替代方案,它构建了更高效的查询,而不是(在合并的情况下)任意长的MERGE语句序列。版本4应在下个月(2018年5月)的某个时候发布。