我有两个独立的操作:
MATCH ()<-[r:waitsFor]-()
SET r.active = true
和
MATCH (start:Job) WHERE has(start.startedAt) OR has(start.completedAt)
OPTIONAL MATCH (prev:Job)<-[r:waitsFor]-(start:Job)
SET r.active = false
它们在大约5s内执行4k节点和2k关系。 但是,如果使用 WITH
立即执行此操作MATCH ()<-[r:waitsFor]-()
SET r.active = true
WITH null AS none
MATCH (start:Job) WHERE has(start.startedAt) OR has(start.completedAt)
OPTIONAL MATCH (prev:Job)<-[r:waitsFor]-(start:Job)
SET r.active = false
查询不会在合理的时间内执行。 我读过 WITH 文档。关于导致此类行为的 WITH ,我怎么理解?
答案 0 :(得分:1)
不要那样做。正如您所说,它们是单独的查询,因此请单独运行它们。现在运行它们的方式是,对第一个中的每个匹配结果执行第二个查询。我正在使用的一个微小的本体图中的示例,其中146个节点标记为:OwlClass
。考虑以下两个查询
- 查询1 -
MATCH (c:OwlClass)
RETURN COUNT(*)
结果:
COUNT(*)
146
Returned 1 row in 102 ms
执行计划:
==> ColumnFilter(symKeys=[" INTERNAL_AGGREGATE01b2d10b-7bf4-43b4-a67d-fbe826c7a4dd"], returnItemNames=["COUNT(*)"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=[], aggregates=["( INTERNAL_AGGREGATE01b2d10b-7bf4-43b4-a67d-fbe826c7a4dd,CountStar())"], _rows=1, _db_hits=0)
==> NodeByLabel(label="OwlClass", identifier="c", _rows=146, _db_hits=0)
- 查询2 -
MATCH (c:OwlClass)
WITH null as n
MATCH (d:OwlClass)
RETURN COUNT(*)
结果:
COUNT(*)
21316
Returned 1 row in 734 ms
执行计划:
==> ColumnFilter(symKeys=[" INTERNAL_AGGREGATEe33d15c7-e357-4e32-9f7f-3fbc00dd58f6"], returnItemNames=["COUNT(*)"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=[], aggregates=["( INTERNAL_AGGREGATEe33d15c7-e357-4e32-9f7f-3fbc00dd58f6,CountStar())"], _rows=1, _db_hits=0)
==> NodeByLabel(label="OwlClass", identifier="d", _rows=21316, _db_hits=0)
==> ColumnFilter(symKeys=["c", "n"], returnItemNames=["n"], _rows=146, _db_hits=0)
==> Extract(symKeys=["c"], exprKeys=["n"], _rows=146, _db_hits=0)
==> NodeByLabel(label="OwlClass", identifier="c", _rows=146, _db_hits=0)
- 查询3 -
MATCH (c:OwlClass)
WITH COUNT(c) as count_c
MATCH (d:OwlClass)
RETURN count_c, COUNT(d) as count_d
结果:
count_c count_d
146 146
Returned 1 row in 153 ms
执行计划:
==> ColumnFilter(symKeys=["count_c", " INTERNAL_AGGREGATE17be6af7-abbb-4ef7-8250-ff050d6ba7c6"], returnItemNames=["count_c", "count_d"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=["count_c"], aggregates=["( INTERNAL_AGGREGATE17be6af7-abbb-4ef7-8250-ff050d6ba7c6,Count(d))"], _rows=1, _db_hits=0)
==> NodeByLabel(label="OwlClass", identifier="d", _rows=146, _db_hits=0)
==> ColumnFilter(symKeys=[" INTERNAL_AGGREGATE67abdc54-9c44-4353-bf82-e4aff895141e"], returnItemNames=["count_c"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=[], aggregates=["( INTERNAL_AGGREGATE67abdc54-9c44-4353-bf82-e4aff895141e,Count(c))"], _rows=1, _db_hits=0)
==> NodeByLabel(label="OwlClass", identifier="c", _rows=146, _db_hits=0)
-
从下往上阅读执行计划。在这种情况下,相关部分是行数如何变化。比较查询2和3的粗略解释。
查询2
OwlClass
的所有节点。现在有146种匹配模式。 OwlClass
的所有节点来继续每个模式。现在有146 * 146 = 21316匹配模式。 查询3
OwlClass
的所有节点。现在有146种匹配模式。 OwlClass
的所有节点来继续每个模式。现在有146种匹配模式。答案 1 :(得分:0)
WITH子句用于将返回的信息“转发”到查询的另一部分。使用WITH null作为none并向前移动以执行后续匹配很容易在Neo4j中创建笛卡尔积。根据节点数量的不同,笛卡尔产品爆炸可能会非常庞大,需要花费大量时间才能完成。
因此,如果第二个查询中第一个查询中的'r'需要缩小匹配范围,则应使用WITH r。因为似乎不是这种情况(因为你使用WITH null作为无),这可能不是解决方案。
在我看来,你的情况是按顺序执行两个单独的查询。您应该查看UNION子句。它用于连接两个查询并合并其结果。您拥有的选项是普通的UNION
或UNION ALL
(删除重复项)。