neo4j - Commits are slowing down -


neo4j writes slow down after few thousand records written.

two indexes exist speed query up. also, using explain know each query constant time process.

        indexorder = schema.indexfor(order)                 .on("id")                 .create();         indexshop = schema.indexfor(shop)                 .on("domain") 

this query use:

 {json} log   log.order order, log.shop 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 

here how commit store db:

private void log() {     try (transaction tx = graphdb.begintx()) {         (map map : list) {             graphdb.execute(query,                     singletonmap("json", map));          }         list = new arraylist<>();         tx.success();     } } 

and call above when have 1k logs.

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

additional info: use these config settings:

            .setconfig(graphdatabasesettings.pagecache_memory, "512m")             .setconfig(graphdatabasesettings.string_block_size, "60")             .setconfig(graphdatabasesettings.array_block_size, "300") 

this system works 200k entries if done within 1 transaction runs memory issues.

so, why 1k entries/transaction approach grind halt after 5 transactions (5k entries) commited database?

how fix problem?

  1. you should merge on order node itself, allow cypher planner use :order(id) index. (besides, should merge nodes in path pattern before doing merge on path pattern anyway, avoid creating duplicate nodes in circumstances.) change, query (but not yet ideal):

    with {json} log  log.order order, log.shop 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. you should minimize number of calls execute(), each call has lot of overhead. in fact, can make single query handle entire list of 1000 items. so, can change log() code following (i assume list defined list<map<string, object>> or that):

    private void log() {     try (transaction tx = graphdb.begintx()) {         graphdb.execute(query, singletonmap("loglist", list));         list = new arraylist<map<string, object>>();         tx.success();     } } 

    and here corresponding cypher query:

    unwind {loglist} log  log.order order, log.shop 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) 

Comments

Popular posts from this blog

c# - Update a combobox from a presenter (MVP) -

How to understand 2 main() functions after using uftrace to profile the C++ program? -

How to put a lock and transaction on table using spring 4 or above using jdbcTemplate and annotations like @Transactional? -