为什么在此示例中neo4j的插入速度如此之低? [英] Why is neo4j's insert speed so low in this example?

查看:470
本文介绍了为什么在此示例中neo4j的插入速度如此之低?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用最新的spring数据neo4j 4测试插入速度. 我修改了电影示例,以使事情变得简单且具有可比性.

I wanted to test insert speed with the latest spring-data neo4j 4 . I modified the movies example to make things simple and comparable.

尝试运行测试类: 电影.spring.data.neo4j.repositories.PersonRepository在这里测试.

Try running the test class: movies.spring.data.neo4j.repositories.PersonRepositoryTest here.

在此示例中,添加400个节点需要5秒钟. https://github.com/fodon/neo4j-spring-data-speed-demo

It takes 5sec to add 400 nodes in this example. https://github.com/fodon/neo4j-spring-data-speed-demo

这是对较旧版本的neo4j的速度测试 https://github.com/fodon/gs-accessing-data-neo4j-speed

This is a speed test with the older version of neo4j https://github.com/fodon/gs-accessing-data-neo4j-speed

同一工作的hello.Application类比spring-data-neo4j-4快40倍.

The hello.Application class is about 40x faster than spring-data-neo4j-4 for the same job.

为什么spring-data-neo4j-4比旧版本慢? 如何加快速度?

Why is spring-data-neo4j-4 slower than the older version? How can it be sped up?

推荐答案

save()的调用实际上是对数据库的直接永久请求.当前没有延迟save()调用的概念.

A call to save() is actually a direct persitence request against the database. There is currently no notion of defering save() calls.

通过将logback-test.xml文件添加到测试资源来打开查询日志记录:

By turning on query logging by adding a logback-test.xml file to your test resources :

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d %5p %40.40c:%4L - %m%n</pattern>
        </encoder>
    </appender>

    <logger name="org.neo4j.ogm" level="info" />


    <root level="info">
        <appender-ref ref="console" />
    </root>

</configuration>

您可以看到,每个Person.save()实际上都会发出3个请求:

You can see that for each Person.save() it will actually make 3 requests :

  • 1个用于保存Car对象的对象
  • 1用于保存Person对象
  • 1用于创建关系

-

2016-07-25 05:27:51,093  INFO drivers.embedded.request.EmbeddedRequest: 155 - Request: UNWIND {rows} as row CREATE (n:`Car`) SET n=row.props RETURN row.nodeRef as nodeRef, ID(n) as nodeId with params {rows=[{nodeRef=-590487524, props={type=f27dc1bac12a480}}, {nodeRef=-1760792732, props={type=41ff5d3a69b4a5b4}}, {nodeRef=-637840556, props={type=3e7e77ca5e406a21}}]}
2016-07-25 05:27:54,117  INFO drivers.embedded.request.EmbeddedRequest: 155 - Request: UNWIND {rows} as row CREATE (n:`Person`) SET n=row.props RETURN row.nodeRef as nodeRef, ID(n) as nodeId with params {rows=[{nodeRef=-1446435394, props={name=bafd7ad2721516f8}}]}
2016-07-25 05:27:54,178  INFO drivers.embedded.request.EmbeddedRequest: 155 - Request: UNWIND {rows} as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId MATCH (endNode) WHERE ID(endNode) = row.endNodeId MERGE (startNode)-[rel:`HAS`]->(endNode) RETURN row.relRef as relRefId, ID(rel) as relId with params {rows=[{startNodeId=3, relRef=-712176789, endNodeId=0}, {startNodeId=3, relRef=-821487247, endNodeId=1}, {startNodeId=3, relRef=-31523689, endNodeId=2}]}

如果将Person创建的语句仅一次使用100个人作为参数,而Car对象也使用相同的参数,则性能会更好.

The performance would be better if instead the statement for the Person creation would just use as parameter the 100 persons at once, and same for the Car objects.

截至目前,OGM中没有本地可用的功能(已发行的问题: https://github.com/neo4j/neo4j-ogm/issues/208

As of now there is no native out of the box feature in the OGM (opened issue : https://github.com/neo4j/neo4j-ogm/issues/208

但是,您可以按saving一个集合而不是一个一个地对它们进行批处理:

However, you can batch them by saving a collection instead of one by one :

@Test
@DirtiesContext
public void speedTest2() {
    SessionFactory sessionFactory = new SessionFactory("hello.neo.domain");
    Session session = sessionFactory.openSession();
    Random rand = new Random(10);
    System.out.println("Before linking up with Neo4j...");
    long start = System.currentTimeMillis();
    long mark = start;
    for (int j = 0; j < 10; j++) {
        List<Person> batch = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            Person greg = new Person(rand);
            batch.add(greg);
        }
        session.save(batch);
        long now = System.currentTimeMillis();
        System.out.format("%d : Time:%d\n", j, now - mark);
        mark = now;
    }
}

您会看到结果差异非常明显:

You can see that the results difference is very impressive:

Not initialzing DB.
Before linking up with Neo4j...
0 : Time:7318
1 : Time:1731
2 : Time:1555
3 : Time:1481
4 : Time:1237
5 : Time:1176
6 : Time:1101
7 : Time:1094
8 : Time:1114
9 : Time:1015
Not initialzing DB.
Before linking up with Neo4j...
0 : Time:494
1 : Time:272
2 : Time:230
3 : Time:442
4 : Time:320
5 : Time:247
6 : Time:284
7 : Time:288
8 : Time:366
9 : Time:222

这篇关于为什么在此示例中neo4j的插入速度如此之低?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆