我想在我的 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);
}
我的新风险数组包含大约 60000 个对象和 60000 条边。每个节点和边都有一个属性。 此循环的持续时间约为 15 - 20 分钟,这正常吗? 我使用 Java VisualVM 来搜索一些瓶颈,但我的平均 CPU 使用率为 10 - 25%(4 个内核),而且我的堆还不到一半。
有什么选项可以提高这个操作?
编辑:另外,在第一次调用 myRepository.save(newRisks.get(i));
时,jvm 在第一次输出前几分钟进入休眠状态来了
第二次编辑:
类风险:
@NodeEntity
public class Risk {
//...
@Indexed
public String name;
@RelatedTo(type = "CHILD", direction = Direction.OUTGOING)
Set<Risk> risk = new HashSet<Risk>();
public void addChild(Risk child) {
risk.add(child);
}
//...
}
创造风险:
@Autowired
private Repository myRepository;
@Transactional
public Collection<Risk> makeSomeRisks() {
ArrayList<Risk> newRisks = new ArrayList<Risk>();
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 进行批量插入。
您创建了一个 Risk 和 60k 个 child ,您首先保存了根,它同时保留了 60k 个 child (并创建了关系)。这就是第一次保存需要这么长时间的原因。然后你又救了 children 。
有一些解决方案可以通过 SDN 加速它。
不要使用集合方法进行批量插入,保留两个参与者并使用 template.createRelationshipBetween(root, child, "CHILD",false);
先持久化子对象,然后将所有持久化的子对象添加到根对象并持久化
像您一样,使用 Neo4j-Core API 但调用 template.postEntityCreation(node,Risk.class) 以便您可以通过 SDN 访问实体。然后你还必须自己索引实体 (db.index.forNodes("Risk").add(node,"name",name);)(或使用 neo4j core-api auto-index,但那不是兼容 SDN)。
无论使用 core-api 还是 SDN,您都应该使用大约 10-20k 节点/rels 的 tx 大小以获得最佳性能
关于java - CRUDRepository 的保存方法很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9568203/