Neo4J Java Bolt CREATE节点很慢。怎么改进呢?

时间:2016-07-10 07:18:01

标签: 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" ) );
        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();
        }
    }
}

结果:

Inserting 58.8235294117647 nodes per second.
Inserting 76.92307692307692 nodes per second.
Inserting 50.0 nodes per second.
Inserting 76.92307692307692 nodes per second.
Inserting 55.55555555555556 nodes per second.
Inserting 62.5 nodes per second.
Inserting 66.66666666666667 nodes per second.
Inserting 55.55555555555556 nodes per second.
Inserting 62.5 nodes per second.
Inserting 55.55555555555556 nodes per second.
Inserting 47.61904761904762 nodes per second.
Inserting 45.45454545454545 nodes per second.
Inserting 58.8235294117647 nodes per second.
Inserting 83.33333333333333 nodes per second.

我使用的是Neo4j 3.0.3和org.neo4j.driver 1.0.4。 插入前图形为空白。 使用的机器有i5 2-2.6GHz CPU和8GB RAM。

LE:我刚刚发现了交易:

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();
}

结果:

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.

性能提升不错。它可以进一步改善吗?

2 个答案:

答案 0 :(得分:2)

您还应该为语句使用参数{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();
}

答案 1 :(得分:1)

在事先添加索引(或唯一约束)时:Person(id)可能不会加速插入(它甚至可能会因为必须更新索引而减慢插入速度),它应该会显着加快以后的操作要求您匹配:人员节点按ID,例如从:人员添加到其他节点的关系或向人员添加属性时。