为什么neo4j这个cypher查询这么慢?

时间:2018-01-20 19:53:40

标签: neo4j cypher

我有一个相当深的树,由一个初始的"交易" node(称为树的第0层),其中有50个边到下一个节点(称之为树的第1个后面),然后从35个左右的每个平均到第二个层,所以上...

初始节点为:txnEvent,其余所有节点均为:mEvent

mEvent个节点有4个属性,其中一个属性称为channel_name

现在,我想检索到第4层的所有路径,以便这些路径包含channel_name==Achannel_name==B的节点

此查询:

match (n: txnEvent)-[r:TO*1..4]->(m:mEvent) return COUNT(*);

告诉我只有1,667,444个路径需要考虑。

但是,以下查询:

MATCH p = (n:txnEvent)-[:TO*1..4]->(m:mEvent)
    WHERE ANY(k IN nodes(p) WHERE k.channel_name='A')
    AND   ANY(k IN nodes(p) WHERE k.channel_name='B')       
    RETURN 
    EXTRACT (n in nodes(p) | n.channel_name),
    EXTRACT (n in nodes(p) | n.step),
    EXTRACT (n in nodes(p) | n.event_type),
    EXTRACT (n in nodes(p) | n.event_device),
    EXTRACT (r in relationships(p) | r.weight )

执行差不多1分钟(neo4j在端口7474上的用户界面)

为了完整性,neo4j告诉我:

"Started streaming 125517 records after 2 ms and completed after 50789 ms, displaying first 1000 rows."

所以我想知道是否有一些显而易见的东西我不知道。节点具有的所有属性都按索引方式编制索引。查询速度慢,还是速度快,流式传输速度慢?

UDATE: 此查询不会回传数据:

MATCH p = (n:txnEvent)-[:TO*1..4]->(m:mEvent)
        WHERE ANY(k IN nodes(p) WHERE k.channel_name='A')
        AND   ANY(k IN nodes(p) WHERE k.channel_name='B')       
        RETURN 
        COUNT(*)

需要35秒,所以即使它更快,大概是因为没有返回数据,我觉得它仍然很慢。

更新2:

enter image description here 理想情况下,这些数据应该放入带有python内核的jupyter笔记本中。

1 个答案:

答案 0 :(得分:1)

感谢您的PROFILE计划。

请记住,您要求的查询很难处理。由于您需要路径中路径中至少有一个节点具有一个属性且路径中至少有一个其他节点具有另一个属性的路径,因此在扩展期间无法修剪路径。相反,必须确定每个可能的路径,然后必须访问这160万个路径中的每个路径中的每个节点以检查属性(对于两个属性,每个路径必须完成两次)。因此,过滤器操作的命中率为~1000万次。

您可以尝试扩展堆和页面缓存大小(如果您有备用RAM),但我没有看到任何简单的方法来调整此查询。

关于查询时间与流式传输的问题,问题在于查询本身。您看到的消息意味着第一个结果发现非常快,因此第一个结果几乎立即就在流中准备好了。结果会在找到时添加到流中,但是在扩展期间需要匹配和过滤的路径量无法修剪路径,这意味着查询完成​​需要很长时间。