Heroku neo4j复杂分层密码查询性能缓慢

Heroku neo4j复杂分层密码查询性能缓慢,heroku,neo4j,cypher,Heroku,Neo4j,Cypher,我有一个复杂的分层查询,如下所示: MATCH (comp:Company {id: 7})-[:HAS_SPACE]->(s:Space)-[:HAS_BOARD]->(b), (col)<-[:HAS_COLUMN]-(b)-[:HAS_LANE]->(lane) OPTIONAL MATCH (b)-[:HAS_CARD]->(card {archived: false}), (cardCol:Column)-[:HAS_CARD]->(card {ar

我有一个复杂的分层查询,如下所示:

MATCH (comp:Company {id: 7})-[:HAS_SPACE]->(s:Space)-[:HAS_BOARD]->(b),
(col)<-[:HAS_COLUMN]-(b)-[:HAS_LANE]->(lane)
OPTIONAL MATCH (b)-[:HAS_CARD]->(card {archived: false}),
(cardCol:Column)-[:HAS_CARD]->(card {archived: false})<-[:HAS_CARD]-(cardLane:Lane)
WITH s, b, col, lane, { id: card.id, title: card.title, sort_order: card.sort_order, column_id: cardCol.id, lane_id: cardLane.id } as crd
WITH s, { id: b.id, title: b.title, left: b.left, top: b.top,
columns: collect(distinct {id: col.id, title: col.title, col_count: col.col_count, sort_order: col.sort_order}), 
lanes: collect(distinct {id: lane.id, title: lane.title, row_count: lane.row_count, sort_order: lane.sort_order}), 
cards: collect(distinct crd)} as brd 
RETURN {id: s.id, title: s.title, boards: collect(distinct brd)}
匹配(comp:Company{id:7})-[:HAS_SPACE]->(s:SPACE)-[:HAS_BOARD]->(b),
(山坳)(里)
可选匹配(b)-[:HAS_CARD]->(CARD{archived:false}),

(cardCol:Column)-[:HAS_CARD]->(CARD{archived:false})经过一些研究发现,如果我们对节点进行“非规范化”,并在CARD中添加一点lane_id和Column_id,那么该查询的运行速度将提高20倍。但这并不是最快的解决方案,我不喜欢这种消除关系的非规范化。因此,我非常感谢任何其他解决方案

我认为这个查询的一个问题是沿路径的组合爆炸,您可以帮助cypher一点(下一个版本将更聪明)

还有,你的“可选关系”在哪里?在棋盘和卡片之间

create index on :Company(id);

MATCH (comp:Company {id: 7})-[:HAS_SPACE]->(s:Space)-[:HAS_BOARD]->(b)
WITH distinct s, b
MATCH  (col)<-[:HAS_COLUMN]-(b)-[:HAS_LANE]->(lane)
OPTIONAL MATCH (b)-[:HAS_CARD]->(card {archived: false})
WITH distinct s, b, col, lane, b, card
MATCH (cardCol:Column)-[:HAS_CARD]->(card {archived: false})<-[:HAS_CARD]-(cardLane:Lane)

WITH s, b, col, lane, 
  { id: card.id, title: card.title, sort_order: card.sort_order, 
    column_id: cardCol.id, lane_id: cardLane.id } as crd

WITH s, 
  { id: b.id, title: b.title, left: b.left, top: b.top,
    columns: collect(distinct {id: col.id, title: col.title, 
                               col_count: col.col_count, sort_order: col.sort_order}), 
    lanes: collect(distinct {id: lane.id, title: lane.title, row_count: lane.row_count, 
                              sort_order: lane.sort_order}), 
    cards: collect(distinct crd)} as brd 

RETURN {id: s.id, title: s.title, boards: collect(distinct brd)}
创建索引:公司(id);
匹配(comp:Company{id:7})-[:HAS_SPACE]->(s:SPACE)-[:HAS_BOARD]->(b)
具有不同的s,b
赛道(山口)
可选匹配(b)-[:HAS_CARD]->(CARD{archived:false})
具有不同的s、b、col、lane、b、card

匹配(cardCol:Column)-[:HAS_CARD]->(CARD{archived:false})您有索引吗?看起来您应该为“已存档”和“id”编制索引。你可能会考虑在这些匹配中添加标签,这可能有助于Syth.hanx。是的,我在id上有一个索引。此外,只有一家公司,所以在这种情况下,索引并不重要。对于归档,只有两个选项:true和false在这种情况下索引会有帮助吗?“你可能会考虑在这些匹配中添加标签”——你是什么意思?通过添加标签,我的意思是你的查询有一个没有标记的节点(B);根据图表的结构,通过使数据库考虑较少可能的候选节点,指示匹配的标签可能会加快匹配速度。但您在这里花费的大部分时间可能是在collect(distinct())位扩展中,所有这些节点实际上都有标签,但它们不用于查询。你的意思是在帮助下明确地使用它们吗?“但您在这里花费的大部分时间可能是在collect(distinct())位”-是的,我也认为这可能是问题所在,但我需要使用distinct,否则collect中会有重复项。我仍然无法理解neo4j在200个节点上的速度为何如此之慢……也许您可以在某个地方共享您的数据库tump。并可能在neo4j shell中创建一个“profile match…”输出,以显示cypher如何运行此查询。谢谢你,Michael,你的版本执行速度比初始查询快10倍。好奇的是,有没有什么好的指南来指导如何编写复杂的查询并避免这样的错误?我还在web客户端中尝试了cypher 2.1.1,但没有显示任何有价值的信息,或者我遗漏了什么。此查询比初始查询快,但仍然会随着数据量的增加而降级。我猜组合爆炸在这里上升:(cardCol:Column)-[:HAS_CARD]->(CARD{archived:false})