2017-04-07 8 views
0

数千のレコードが書き込まれた後、Neo4jはスローダウンします。コミットが遅くなります

クエリを高速化するために2つのインデックスが存在します。 また、EXPLAINを使用して、各クエリが一定の時間プロセスであることを知っています。

 indexOrder = schema.indexFor(ORDER) 
       .on("id") 
       .create(); 
     indexShop = schema.indexFor(SHOP) 
       .on("domain") 

これは私が使用するクエリです:

private void log() { 
    try (Transaction tx = graphDb.beginTx()) { 
     for (Map map : list) { 
      graphDb.execute(query, 
        singletonMap("json", map)); 

     } 
     list = new ArrayList<>(); 
     tx.success(); 
    } 
} 

そして、私は1kのログを持っているとき、私は上記を呼び出します。ここでは

WITH {json} as log 
WITH log.order as order, log.shop as shop 
MERGE (s:Shop {domain:shop.domain}) 
    ON CREATE SET s=shop 
MERGE (s)-[:Scored]->(r:Order {id:order.id}) 
    ON CREATE SET r=order 

は、私がDBに格納それをコミットする方法です。

 list.add(map); 
     count++; 
     if (count % 1000 == 0) { 
      log(); 
      System.out.println(count); 
     } 

追加情報:私はこれらの設定の設定を使用します。

  .setConfig(GraphDatabaseSettings.pagecache_memory, "512M") 
      .setConfig(GraphDatabaseSettings.string_block_size, "60") 
      .setConfig(GraphDatabaseSettings.array_block_size, "300") 

そのすべてが1つのトランザクション内で行われたが、その後メモリの問題に実行する場合、このシステムは200Kエントリに動作します。

なぜ、わずか5トランザクション(5kエントリ)がデータベースにコミットされた後、1kエントリ/トランザクションアプローチが停止するのはなぜですか?

問題を解決するにはどうすればよいですか?

答えて

2
  1. あなたは、サイファープランナーが:Order(id)インデックスを使用できるようにするために、それ自体でOrderノード上MERGEを行う必要があります。 (また、MERGEの前にの前にパスパターンのノードを作成すると、特定の状況でノードが重複しないようにする必要があります)。この変更により、クエリは次のようになります理想的な):

    WITH {json} as log 
    WITH log.order as order, log.shop as shop 
    MERGE (s:Shop {domain:shop.domain}) 
        ON CREATE SET s=shop 
    MERGE (r:Order {id:order.id}) 
        ON CREATE SET r=order 
    MERGE (s)-[:Scored]->(r) 
    
  2. 各呼び出しはオーバーヘッドをたくさん持っているとあなたは、​​へのコールの数を最小限に抑える必要があります。実際、1000項目のlist全体を処理する単一のクエリを簡単に作成できます。だから、あなたは(私はlistList<Map<String, Object>>またはそのような何かになるように定義されていると仮定)以下に、あなたのlog()コードを変更することができます

    UNWIND {logList} as log 
    WITH log.order as order, log.shop as shop 
    MERGE (s:Shop {domain:shop.domain}) 
        ON CREATE SET s=shop 
    MERGE (r:Order {id:order.id}) 
        ON CREATE SET r=order 
    MERGE (s)-[:Scored]->(r) 
    

private void log() { 
    try (Transaction tx = graphDb.beginTx()) { 
     graphDb.execute(query, singletonMap("logList", list)); 
     list = new ArrayList<Map<String, Object>>(); 
     tx.success(); 
    } 
} 

、ここでは、対応するサイファークエリです

+0

はい、それは素晴らしいです! – fodon

関連する問題