Neo4j:cypher执行和JavaAPI调用之间的区别?

Neo4j:cypher执行和JavaAPI调用之间的区别?,neo4j,cypher,Neo4j,Cypher,Neo4j:企业版3.2 在速度方面,我看到了以下两个调用之间的巨大差异。以下是设置和查询/API 页面缓存:16g|堆:16g 行/节点数->600K 密码(忽略语法,如果有的话)|所用时间:50秒 using periodic commit 10000 load with headers from 'file:///xyx.csv' as row with row create(n:ObjectTension) set n = row 来自Java(会话池,以每次15个会话为例): 线程1

Neo4j:企业版3.2

在速度方面,我看到了以下两个调用之间的巨大差异。以下是设置和查询/API

页面缓存:16g|堆:16g

行/节点数->600K

密码(忽略语法,如果有的话)|所用时间:50秒

using periodic commit 10000
load with headers from 'file:///xyx.csv' as row with row
create(n:ObjectTension) set n = row
来自Java(会话池,以每次15个会话为例):

线程1:所用时间:8秒/10K

   Map<String,Object> pList = new  HashMap<String, Object>();

   try(Transaction tx = Driver.session().beginTransaction()){
      for(int i = 0; i< 10000; i++){
         pList.put(i, i * i);
         params.put("props",pList);
         String query = "Create(n:Label {props})";
         // String query = "create(n:Label) set n = {props})";
          tx.run(query, params);
   }
Map pList=new HashMap();
try(事务tx=Driver.session().beginTransaction()){
对于(int i=0;i<10000;i++){
pList.put(i,i*i);
参数put(“道具”,pList);
String query=“创建(n:Label{props})”;
//字符串查询=“创建(n:Label)集合n={props}”;
tx.run(查询、参数);
}
线程2:所用时间为9秒/10K

   Map<String,Object> pList = new  HashMap<String, Object>();
   try(Transaction tx = Driver.session().beginTransaction()){
      for(int i = 0; i< 10000; i++){
         pList.put(i, i * i);
         params.put("props",pList);
         String query = "Create(n:Label {props})";
         // String query = "create(n:Label) set n = {props})";
          tx.run(query, params);
   }
.
.
.
Thread_3 : Basically the above code is reused..It's just an example.
Map pList=new HashMap();
try(事务tx=Driver.session().beginTransaction()){
对于(int i=0;i<10000;i++){
pList.put(i,i*i);
参数put(“道具”,pList);
String query=“创建(n:Label{props})”;
//字符串查询=“创建(n:Label)集合n={props}”;
tx.run(查询、参数);
}
.
.
.
线程3:基本上上面的代码是重用的。这只是一个例子。
螺纹N,其中N=(600K/10K)

因此,总的时间约为2~3分钟

问题如下?

  • CSV load在内部是如何处理的?就像它在内部打开单个会话和多个事务一样
  • 根据作为“使用周期提交10000”传递的参数创建多个会话,此600K/10000为60会话?等

  • 通过Java编写的最佳方式是什么

  • 其思想是通过Java实现与CSV加载相同的写入性能。由于CSV在~5秒内加载12000个节点,甚至更好。

    您的Java代码与您的Cypher代码做的事情非常不同,因此比较处理时间真的没有意义

    您应该将Java代码更改为从同一个CSV文件中读取。文件IO相当昂贵,但Java代码没有这样做

    此外,虽然纯密码查询创建的节点具有固定数量的属性(可能相对较少),但Java
    pList
    的大小随着每次循环迭代而不断增长——因此每个Java循环创建的节点具有1到10K的属性!这可能是Java代码速度慢得多的主要原因

    [更新1]

    如果您想忽略使用和不使用CSV文件之间的性能差异,以下(未测试)代码应该让您了解Java中类似的逻辑。在本例中,
    i
    循环假设您的CSV文件有10列(您应该调整循环以使用正确的列计数)。此外,此示例为所有节点提供了相同的属性,只要您没有创建相反的唯一性约束,就可以了

    Session session = Driver.session();
    
    Map<String,Object> pList = new HashMap<String, Object>();
    for (int i = 0; i < 10; i++) {
        pList.put(i, i * i);
    }
    
    Map<String, Map> params = new HashMap<String, Map>();
    params.put("props", pList);
    
    String query = "create(n:Label) set n = {props})";
    
    for (int j = 0; j < 60; j++) {
        try (Transaction tx = session.beginTransaction()) {
            for(int k = 0; k < 10000; k++){
                tx.run(query, params);
            }
        }
    }
    

    您可以尝试使用Java API创建节点,而不是依赖密码:

    • createNode
      -
    • setProperty
      -
    另外,正如前面提到的,
    props
    变量对于您的案例具有不同的值


    另外,请注意,每次执行查询解析的迭代(
    stringquery=“Create(n:Label{props})”;
    )-除非neo4j自己对其进行了优化。

    如果在我打开事务之前准备好pList怎么办?上面显示的代码示例是为了让我了解如何将xyz.csv中的文件划分为块,并执行与csv加载相同的操作?我的问题基本上是关于会话和事务。什么这样做是正确的。最好不要以现有答案和注释不再有意义的方式编辑您的问题。StackOverflow是为所有有类似问题的人服务的,因此我们应该确保问题和答案同步。我已还原了您的原始代码。如果您想显示备用代码,请您可以将其添加到您的问题中,并明确指出这是对原始问题的更新。好的,假设将数据加载到pList的for循环不在try块中。感谢您的回复,这意味着您要求我打开60个会话?可以从会话和事务方面进行更多讨论。因为我想清楚地了解最佳方式。很好。我编辑了我的答案,只创建了一个
    会话
    (我很想知道这段代码实际上是如何执行的。)假设pList退出try块,并且在打开事务之前加载了数据。Map pList=new HashMap();for(int I=0;I<10000;I++){pList.put(i,i*i);params.put(“props”,pList);}try(Transaction tx=Driver.session().beginTransaction()){String query=“Create(n:Label{props})”;//String query=“Create(n:Label)set n={props}”;tx.run(query,params);}
    Map<String, Integer> pList = new HashMap<String, Integer>();
    for (int i = 0; i < 10; i++) {
      pList.put(Integer.toString(i), i*i);
    }
    
    List<Map<String,Integer>> rows = Collections.nCopies(1, pList);
    
    Map<String, List> params = new HashMap<String, List>();
    params.put("rows", rows);
    
    String query = "UNWIND {rows} AS row CREATE(n:Label) SET n = {row})";
    
    for (int j = 0; j < 60; j++) {
      try (Transaction tx = session.beginTransaction()) {
        tx.run(query, params);
      }
    }