保存CRUDRepository的方法很慢?

我想在我的neo4j数据库中存储一些数据。 我使用spring-data-neo4j。

我的代码如下:

for (int i = 0; i < newRisks.size(); i++) { myRepository.save(newRisks.get(i)); System.out.println("saved " + newRisks.get(i).name); } 

我的newRisks-array包含大约60000个对象和60000个边。 每个节点和边都有一个属性。 这个循环的持续时间大约是15-20分钟,这是正常的吗? 我使用Java VisualVM来搜索一些瓶颈,但我的平均CPU使用率为10 – 25%(4个核心),而我的堆不到一半。

有什么选择来推动这项行动吗?


编辑:附加是,在第一次调用myRepository.save(newRisks.get(i)); 在第一个输出到来之前几分钟,jvm下降了fpr

第二次编辑:

类风险:

 @NodeEntity public class Risk { //... @Indexed public String name; @RelatedTo(type = "CHILD", direction = Direction.OUTGOING) Set risk = new HashSet(); public void addChild(Risk child) { risk.add(child); } //... } 

创造风险:

 @Autowired private Repository myRepository; @Transactional public Collection makeSomeRisks() { ArrayList newRisks = new ArrayList(); newRisks.add(new Risk("Root")); for (int i = 0; i < 60000; i++) { Risk risk = new Risk("risk " + (i + 1)); newRisks.get(0).addChild(risk); newRisks.add(risk); } for (int i = 0; i < newRisks.size(); i++) { myRepository.save(newRisks.get(i)); } return newRisks; } 

这里的问题是你正在使用不适用于此的API进行批量插入。

你创建一个风险和60k的孩子,你首先保存根,同时也保持60k儿童(并创建关系)。 这就是为什么第一次保存需要这么长时间。 然后你再次拯救孩子们。

有一些解决方案可以加快SDN的速度。

  1. 不要使用集合方法进行大量插入,保持两个参与者并使用template.createRelationshipBetween(root,child,“CHILD”,false);

  2. 首先坚持孩子,然后将所有持久的孩子添加到根对象并坚持下去

  3. 正如您所做的那样,使用Neo4j-Core API但调用template.postEntityCreation(node,Risk.class),以便您可以通过SDN访问实体。 然后你还必须自己索引实体(db.index.forNodes(“Risk”)。add(node,“name”,name);)(或者使用neo4j core-api auto-index,但那不是与SDN兼容)。

  4. 无论使用core-api还是SDN,您都应该使用大约10-20k节点/ rels的tx大小以获得最佳性能

我想我找到了一个解决方案:

我使用nativ neo4j java API尝试了相同的插入:

 GraphDatabaseService graphDb; Node firstNode; Node secondNode; Relationship relationship; graphDb = new EmbeddedGraphDatabase(DB_PATH); Transaction tx = graphDb.beginTx(); try { firstNode = graphDb.createNode(); firstNode.setProperty( "name", "Root" ); for (int i = 0; i < 60000; i++) { secondNode = graphDb.createNode(); secondNode.setProperty( "name", "risk " + (i+1)); relationship = firstNode.createRelationshipTo( secondNode, RelTypes.CHILD ); } tx.success(); } finally { tx.finish(); graphDb.shutdown(); } 

结果:在几秒之后,数据库充满了风险。

也许reflection会使用spring-data-neo4j减慢这个程序。 @Michael Hunger在他的书GoodRelationships中说了这样的话,谢谢你的提示。

插入到您的数据库(Java之外)是否具有相同的延迟,或者仅通过弹簧数据这是一个问题?

我遇到了与OP相同的问题。 在我的情况下真的很有用的是将Neo4j的使用从远程服务器模式改为嵌入式 。 可以在此处找到嵌入式SDN使用的良好示例。