java - CRUDRepository 的保存方法很慢?

标签 java jvm neo4j database-performance spring-data-neo4j

我想在我的 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 加速它。

  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 大小以获得最佳性能

关于java - CRUDRepository 的保存方法很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9568203/

相关文章:

java - Singleton 类中的非静态成员

java - 什么是 Java 堆栈与 native 内存的映射。

node.js - 使用用于 Nodejs 的 Neo4j-Driver 通过 id 和参数获取 Node

Neo4j 关系属性索引

NEO4J 密码查询 : Multiple Aggregates

java - 实现 hashcode 和 equal 的责任

java - 在 recyclerview 中将 3 个 TextView 彼此相邻对齐时遇到问题

Java EE 将 CDI @SessionScoped 注入(inject) EJB @Stateless session bean

java - Java 虚拟机是否在用户登录 Windows 之前启动?

java - Thread.join() 的 JDK 实现