提案正在放缓

时间:2017-04-07 19:08:55

标签: neo4j cypher

在写了几千条记录后,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")

如果所有内容都在一个事务中完成,那么该系统可以处理200k个条目,但后来遇到内存问题。

那么,为什么只有5个事务(5k条目)被提交到数据库后,1k条目/事务处理方法会停止?

如何解决问题?

1 个答案:

答案 0 :(得分:2)

  1. 您应该在MERGE节点上单独执行Order,以允许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. 您应该尽量减少对execute()的呼叫次数,因为每个呼叫都有很多开销。实际上,您可以轻松地创建一个查询来处理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)