2017-04-07 43 views
0

Neo4j在寫入幾千條記錄後寫入速度變慢。提交正在減速

存在兩個索引以加快查詢速度。 另外,使用EXPLAIN我知道每個查詢是一個恆定的時間過程。

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

這是我使用的查詢:

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:

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

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

我調用上面時,我有1K日誌。

 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") 

該系統的工作原理,以20萬項,如果其所有在一個事務內完成,但然後運行到內存的問題。

那麼,爲什麼1k條目/事務方法在5個事務(5k條目)被提交到數據庫之後就停止了?

如何解決問題?

回答

2
  1. 你應該自己做Order節點上的MERGE,允許Cypher支架規劃者使用:Order(id)指數。 (此外,您應該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。所以,你可以改變你的log()代碼如下(我假設list被定義爲List<Map<String, Object>>或類似的東西):

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

    ,這裏是相應的Cypher查詢:

    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) 
    
+0

是的,這太棒了! – fodon