Java 积存的方法很慢吗?

Java 积存的方法很慢吗?,java,jvm,neo4j,database-performance,spring-data-neo4j,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); } 制造风险: @Autowired private Reposi

我想在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);
    }
制造风险:

@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;
}
@Autowired
私有存储库;
@交易的
公共收集风险(){
ArrayList newRisks=新的ArrayList();
新增(新增风险(“根”));
对于(int i=0;i<60000;i++){
风险=新风险(“风险”+(i+1));
newRisks.get(0)、addChild(risk);
新增风险。添加(风险);
}
对于(int i=0;i
数据库中的插入(Java之外)是否也有同样的延迟,或者这只是spring数据的问题?

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

我使用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();
}
GraphDatabaseService graphDb;
节点第一节点;
第二节点;
关系;
graphDb=新的嵌入式GraphDatabase(DB_路径);
事务tx=graphDb.beginTx();
试一试{
firstNode=graphDb.createNode();
setProperty(“名称”、“根”);
对于(int i=0;i<60000;i++){
secondNode=graphDb.createNode();
setProperty(“名称”、“风险”+(i+1));
relationship=firstNode.createRelationshipTo(secondNode,RelTypes.CHILD);
}
成功();
}
最后{
tx.finish();
graphDb.shutdown();
}
结果是: 经过一些讨论后,数据库中充满了风险


也许反射会使spring-data-neo4j的程序变慢@Michael Hunger在他的书中说了类似的话,谢谢你的提示。

这里的问题是,你正在使用一个不适用于此的API进行大规模插入

如果创建了一个风险和60k子项,则首先保存根,同时也保存了60k子项(并创建了关系)。这就是为什么第一次扑救需要这么长时间。然后你又救了孩子们

有一些解决方案可以通过SDN来加快速度

  • 不要对批量插入使用收集方法,持久化参与者并使用template.createRelationshipInterween(root,child,“child”,false)

  • 首先持久化子对象,然后将所有持久化的子对象添加到根对象并持久化该子对象

  • 正如您所做的那样,使用Neo4j Core API但调用template.postEntityCreation(node,Risk.class),这样您就可以通过SDN访问实体。然后您还必须自己为实体编制索引(db.index.forNodes(“Risk”).add(node,“name”,name);)(或者使用Neo4j Core API自动索引,但这与SDN不兼容)

  • 无论使用核心api还是SDN,都应使用大约10-20k节点/rel的发送大小,以获得最佳性能


  • 我面临着与OP相同的问题。在我的案例中,真正有用的是将Neo4j的使用从远程服务器模式改为嵌入式。可以找到嵌入式SDN使用的好例子。

    根据,crudepository.save可以将Iterable作为参数。为什么不仅仅是myRepository.save(newRisks)?我尝试了这个方法,它也很有效。但是,它不是更快。所以我可以看到,他没有死^^你能展示一下你的类的结构以及它所指的任何节点实体和关系实体吗。构建风险实例的方法是什么?交易边界是什么?它应该是方法周围的@Transactional,或者可能是每10k对象提交一次的事务模板。否则,这将为每个对象创建一个tx,这将带来大量开销。@Michael Hunger感谢您提出的其他问题,我在我的postgood idea中的“Second EDIT:”下添加了信息,但是如何从java中插入注释等的计数?我不想学习其他编程语言。另一个想法是:我可以尝试使用标准的Neo4jJavaAPI,而不是spring-data-neo4j。这将在任何编程语言之外测试数据库本身的速度。这是一个noSQL数据库,但我已经用neo4j的natic java api尝试过了,很快就知道你是对的。第一次我只保存根,只需要6分钟。也许以后我得试试你提出的其他解决办法。
    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();
    }