Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4J Java Bolt创建节点速度较慢。如何改进?_Java_Performance_Neo4j - Fatal编程技术网

Neo4J Java Bolt创建节点速度较慢。如何改进?

Neo4J Java Bolt创建节点速度较慢。如何改进?,java,performance,neo4j,Java,Performance,Neo4j,我尝试使用以下代码插入一组节点Neo4J: import org.neo4j.driver.v1.*; public class BoltClass { public static void minimalWorkingExample() throws Exception { Driver driver = GraphDatabase.driver( "bolt://localhost", AuthTokens.basic( "neo4j", "admin4j"

我尝试使用以下代码插入一组节点Neo4J:

import org.neo4j.driver.v1.*;

public class BoltClass
{
    public static void minimalWorkingExample() throws Exception
    {
        Driver driver = GraphDatabase.driver( "bolt://localhost", AuthTokens.basic( "neo4j", "admin4j" ) );
        Session session = driver.session();

        int k=0;

        for (int i = 0; i < 1000; i++) {
            int count = 1000;
            long begin = System.currentTimeMillis();
            for (int j = 0; j < count; j ++) {
                session.run("CREATE (a:Person {id:" + k + ", name:'unknown'})");
            }
            long end = System.currentTimeMillis();
            System.out.print("Inserting " + (double)count/((double)(end-begin)/count) + " nodes per second.\n");
            k++;
        }

        session.close();
        driver.close();
    }

    public static void main(String[] args)
    {
        try {
            minimalWorkingExample();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
我使用的是Neo4j 3.0.3和org.Neo4j.driver 1.0.4。 插入之前,图表是空白的。 使用的机器具有i5 2-2.6GHz CPU和8GB RAM

乐:我刚刚发现了交易:

public static void TransactionExample() throws Exception
{
    Driver driver = GraphDatabase.driver( "bolt://localhost", AuthTokens.basic( "neo4j", "admin4j" ) );
    Session session = driver.session();

    int k=0;
    for (int i = 0; i < 1000; i++) {
        int count = 1000;
        long begin = System.currentTimeMillis();

        try ( Transaction tx = session.beginTransaction() )
        {
            for (int j = 0; j < count; j ++) {
                tx.run("CREATE (a:Person {id:" + k + ", name:'unknown'})");
            }
            tx.success();
        }
        long end = System.currentTimeMillis();
        System.out.print("Inserting " + (double)count/((double)(end-begin)/count) + " nodes per second.\n");
        k++;
    }
    session.close();
    driver.close();
}

很好的性能提升。是否可以进一步改进?

在:Person(id)上预先添加索引(或唯一约束)可能不会加快插入速度(它甚至可能会减慢插入速度,因为它必须更新索引),但它会显著加快以后需要按id匹配:Person节点的任何操作,例如,在向其他节点添加从:Person到其他节点的关系或向Person添加属性时。

您还应该为语句使用参数
{id}
{name}
参数,否则Cypher必须重新解析并重新编译您的每个查询。通过参数,它可以编译一次并重新使用已编译的计划

您还应该在内部循环中增加
k

public static void TransactionExample() throws Exception
{
    Driver driver = GraphDatabase.driver("bolt://localhost", AuthTokens.basic("neo4j", "admin4j"));
    Session session = driver.session();
    int k=0;
    String query = "CREATE (a:Person {id:{id}, name:{name}})";
    for (int i = 0; i < 1000; i++) {
        int count = 1000;
        long begin = System.currentTimeMillis();

        try (Transaction tx = session.beginTransaction())
        {
            for (int j = 0; j < count; j++) {
                tx.run(query, Values.parameters("id", k, "name", unknown));
                k++;
            }
            tx.success();
        }
        long end = System.currentTimeMillis();
        System.out.print("Inserting " + (double)count/((double)(end-begin)/count) + " nodes per second.\n");
    }
    session.close();
    driver.close();
}
public static void TransactionExample()引发异常
{
驱动程序驱动程序=图形数据库。驱动程序(“bolt://localhost,AuthTokens.basic(“neo4j”、“admin4j”);
Session Session=driver.Session();
int k=0;
String query=“创建(a:Person{id:{id},name:{name})”;
对于(int i=0;i<1000;i++){
整数计数=1000;
long begin=System.currentTimeMillis();
try(事务tx=session.beginTransaction())
{
对于(int j=0;j
改进得不错。非常感谢。请在CYPHER语句中添加一个缺少的花括号,因为它不允许我编辑您的帖子。回答得好。用
try(…)
包装事务是否意味着
tx.close()
会被自动调用?@AviranKatz显然是的。声明“当此方法返回时,会话中所有未完成的语句都保证已完成,这意味着您执行的任何写入操作都保证被持久存储。”请注意,从v4.x.x开始,旧的参数语法
{param}
不再受支持。请改用
$param
,因此“创建(a:Person{id:$id,name:$name}”;
Inserting 20000.0 nodes per second.
Inserting 17857.142857142855 nodes per second.
Inserting 18867.924528301886 nodes per second.
Inserting 15384.615384615385 nodes per second.
Inserting 19607.843137254902 nodes per second.
Inserting 16666.666666666668 nodes per second.
Inserting 16393.44262295082 nodes per second.
public static void TransactionExample() throws Exception
{
    Driver driver = GraphDatabase.driver("bolt://localhost", AuthTokens.basic("neo4j", "admin4j"));
    Session session = driver.session();
    int k=0;
    String query = "CREATE (a:Person {id:{id}, name:{name}})";
    for (int i = 0; i < 1000; i++) {
        int count = 1000;
        long begin = System.currentTimeMillis();

        try (Transaction tx = session.beginTransaction())
        {
            for (int j = 0; j < count; j++) {
                tx.run(query, Values.parameters("id", k, "name", unknown));
                k++;
            }
            tx.success();
        }
        long end = System.currentTimeMillis();
        System.out.print("Inserting " + (double)count/((double)(end-begin)/count) + " nodes per second.\n");
    }
    session.close();
    driver.close();
}