使用大量节点从节点复制属性很慢

时间:2015-08-13 23:48:38

标签: neo4j cypher

我在标记的节点中迁移某些属性,但查询性能非常差。

旧属性是callerRef,新属性是代码。需要更新的17m节点我想要批量处理。实体上没有代码属性表明它尚未升级。

profile match (e:Entity) where not has(e.code) with e limit 1000000 set e.key = e.callerKeyRef, e.code = e.callerRef;

实体标签中有一个索引,用于代码。

schema -l :Entity
Indexes
  ON :Entity(code) ONLINE
No constraints

堆有8gbs分配运行Neo4j 2.2.4。如果我正确地阅读计划,问题是即使指定了limit子句,标签中的所有节点也都会被命中。我原以为在无序查询中,请求限制,处理将在满足限制条件后停止。

+-------------------+
| No data returned. |
+-------------------+
Properties set: 2000000
870891 ms

Compiler CYPHER 2.2

+-------------+----------+----------+-------------+--------------------------+
|    Operator |     Rows |   DbHits | Identifiers |                    Other |
+-------------+----------+----------+-------------+--------------------------+
| EmptyResult |        0 |        0 |             |                          |
| UpdateGraph |  1000000 |  6000000 |           e | PropertySet; PropertySet |
|       Eager |  1000000 |        0 |           e |                          |
|       Slice |  1000000 |        0 |           e |             {  AUTOINT0} |
|      Filter |  1000000 | 16990200 |           e |     NOT(hasProp(e.code)) |
| NodeByLabel | 16990200 | 16990201 |           e |                  :Entity |
+-------------+----------+----------+-------------+--------------------------+

Total database accesses: 39980401

我错过了一些明显的东西吗? TIA

2 个答案:

答案 0 :(得分:2)

仅支持=IN的索引(基本相同,因为Cypher编译器会转换=中的所有IN操作。

Neo4j是无模式数据库。所以,如果没有属性 - 没有索引数据。这就是为什么它需要扫描所有节点。

我的建议:

  • 第一步:将code属性添加到所有必需节点,并使用默认的“falsy”值
  • 使用node.code = "none" where子句
  • 进行更新

答案 1 :(得分:1)

首先将新标签(例如ToDo)分配给尚未迁移的所有节点可能会更快:

MATCH (e:Entity)
WHERE NOT HAS (e.code)
SET e:ToDo;

然后,您可以一次迭代匹配1000000(或其他)ToDo个节点,迁移每个节点后删除ToDo标签:

MATCH (e:ToDo)
WITH e
LIMIT 1000000
SET e.key = e.callerKeyRef, e.code = e.callerRef
REMOVE e:ToDo;