[英]Improve Neo4j Cypher Performance On Lengthy Match
Setup: 设定:
I have the following cypher query that I would like to improve the performance on: 我有以下cypher查询,我想提高性能:
START a=node(2) MATCH (a)-[:knowledge]-(x)-[:depends]-(y)-[:knowledge]-(end) RETURN COUNT(DISTINCT end);
This returns 471 (188171 ms). 返回471(188171 ms)。
Right now I'm only getting a count but later I may want to get the values (471 in this example). 现在我只得到一个计数,但后来我可能想得到这些值(本例中为471)。 The problem is it takes about 3-4 minutes to run. 问题是运行大约需要3-4分钟。
The graph is highly connected with many relationships. 该图与许多关系高度相关。 Running the following shows how many edges of type "knowledge" exist for node a(2). 运行以下内容显示节点a(2)存在多少“知识”类型的边。
START a=node(2) MATCH (a)-[:knowledge]-(x) RETURN COUNT(a);
This returns 4350 (103 ms). 返回4350(103毫秒)。
To me, this doesn't seem like many edges to check. 对我来说,这似乎不是很多边缘要检查。 Can I split this up somehow to improve performance? 我能否以某种方式将其拆分以提高性能?
edit: As per the comments, here are the results from running the query with profile: 编辑:根据评论,以下是使用配置文件运行查询的结果:
profile START a=node(2) MATCH (a)-[:knowledge]-(x)-[:depends]-(y)-[:knowledge]-(end) RETURN COUNT(DISTINCT end);
==> +---------------------+
==> | COUNT(DISTINCT end) |
==> +---------------------+
==> | 471 |
==> +---------------------+
==> 1 row
==>
==> ColumnFilter(symKeys=[" INTERNAL_AGGREGATEcd2aff18-1c9d-47a8-9217-588cb86bbc1a"], returnItemNames=["COUNT(DISTINCT end)"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=[], aggregates=["( INTERNAL_AGGREGATEcd2aff18-1c9d-47a8-9217-588cb86bbc1a,Distinct)"], _rows=1, _db_hits=0)
==> TraversalMatcher(trail="(a)-[ UNNAMED7:knowledge WHERE true AND true]-(x)-[ UNNAMED8:depends WHERE true AND true]-(y)-[ UNNAMED9:knowledge WHERE true AND true]-(end)", _rows=25638262, _db_hits=25679365)
==> ParameterPipe(_rows=1, _db_hits=0)
I ended up doing the following to improve performance: 我最终做了以下工作以提高性能:
profile START a=node(2) MATCH (a)-[:knowledge]-(x) WITH DISTINCT x MATCH (x)-[:depends]-(y) WITH DISTINCT y MATCH (y)-[:knowledge]-(end) WITH DISTINCT end RETURN COUNT(end);
==> +------------+
==> | COUNT(end) |
==> +------------+
==> | 471 |
==> +------------+
==> 1 row
==>
==> ColumnFilter(symKeys=[" INTERNAL_AGGREGATE1967576a-d357-457a-b799-adbb16b93048"], returnItemNames=["COUNT(end)"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=[], aggregates=["( INTERNAL_AGGREGATE1967576a-d357-457a-b799-adbb16b93048,Count)"], _rows=1, _db_hits=0)
==> Distinct(_rows=471, _db_hits=0)
==> PatternMatch(g="(end)-[' UNNAMED3']-(y)", _rows=403437, _db_hits=0)
==> Distinct(_rows=735, _db_hits=0)
==> PatternMatch(g="(x)-[' UNNAMED2']-(y)", _rows=1653, _db_hits=0)
==> Distinct(_rows=177, _db_hits=0)
==> TraversalMatcher(trail="(a)-[ UNNAMED1:knowledge WHERE true AND true]-(x)", _rows=4350, _db_hits=4351)
==> ParameterPipe(_rows=1, _db_hits=0)
By making each step a small part in the overall, it reduces the overall complexity and only follows edges that will match. 通过使每个步骤在整体中占很小的一部分,它降低了整体复杂性并且仅遵循将匹配的边缘。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.