我在标记的节点中迁移某些属性,但查询性能非常差。
旧属性是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
答案 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;