Neo4j 非常慢的朋友推荐密码查询

Neo4j 非常慢的朋友推荐密码查询,neo4j,cypher,Neo4j,Cypher,我对Neo4J和graph数据库比较陌生。我使用v2.0创建了一个新的数据库,并用400000个人员节点填充它,2000万人跟踪它们之间的关系。我运行下面的查询,试图找到被我跟踪的人跟踪的人,我还没有跟踪的人。查询速度慢得令人痛苦。我以为它会闪电般的快,因为这似乎是尼奥的强项 我做错了吗?以下是我的疑问: MATCH p=(a:person)-[:follows]->(:person)-[:follows]->(c:person) WHERE a.id = 1000 AND NOT(

我对Neo4J和graph数据库比较陌生。我使用v2.0创建了一个新的数据库,并用400000个人员节点填充它,2000万人跟踪它们之间的关系。我运行下面的查询,试图找到被我跟踪的人跟踪的人,我还没有跟踪的人。查询速度慢得令人痛苦。我以为它会闪电般的快,因为这似乎是尼奥的强项

我做错了吗?以下是我的疑问:

MATCH p=(a:person)-[:follows]->(:person)-[:follows]->(c:person)
WHERE a.id = 1000 AND NOT(a-[:follows]->c)
RETURN c.id, count(p) as count ORDER BY count DESC LIMIT 5;
如果在进入聚合之前使用a、c、p limit 10000限制查询中大约有40000条路径的数量,或者删除NOTa-[:followers]->c,则运行速度似乎要快得多。不幸的是,这两件事我都做不起

如能得到任何建议,我将不胜感激

以下是我个人资料的结果:

==> ColumnFilter(symKeys=["c.personname", "  INTERNAL_AGGREGATE2a433ee6-de88-4555-969c-6057f8b44b3c"], returnItemNames=["c.personname", "cnt"], _rows=5, _db_hits=0)
==> Top(orderBy=["SortItem(Cached(  INTERNAL_AGGREGATE2a433ee6-de88-4555-969c-6057f8b44b3c of type Integer),false)"], limit="Literal(5)", _rows=5, _db_hits=0)
==>   EagerAggregation(keys=["Cached(c.personname of type Any)"], aggregates=["(  INTERNAL_AGGREGATE2a433ee6-de88-4555-969c-6057f8b44b3c,Count(a))"], _rows=16044, _db_hits=0)
==>     Extract(symKeys=["  UNNAMED49", "a", "  UNNAMED50", "c", "  UNNAMED35"], exprKeys=["c.personname"], _rows=42439, _db_hits=42439)
==>       Filter(pred="NOT(nonEmpty(PathExpression((a)-[  UNNAMED78:follows]->(c), true)))", _rows=42439, _db_hits=0)
==>         TraversalMatcher(start={"label": "person", "query": "Literal(170096)", "identifiers": ["a"], "property": "personid", "producer": "SchemaIndex"}, trail="(a)-[  UNNAMED35:follows WHERE true AND true]->(  UNNAMED49)-[  UNNAMED50:follows WHERE true AND true]->(c)", _rows=51500, _db_hits=51786)

正如我所能理解的,执行计划有两个瓶颈,由_db_命中的高值表示。其中一个原因是不必要地读取所有匹配c节点的属性值,然后只返回五个。在读取属性值之前,可以通过将结果限制为5来避免此问题。尝试在WITH子句中同时施加顺序和限制,然后读取并返回这五个节点的属性。像这样的

MATCH (a:person {id:1000})-[:follows]->()-[:follows]->(c) 
WHERE NOT a-[:follows]->c 
WITH c, count(a) as cnt  //carry (c) instead of fetching (c.id)
    ORDER BY cnt
    LIMIT 5
RETURN c.id, cnt  //fetch (c.id) only for the five nodes you are actually interested in

另一个瓶颈是问题的开始,我不知道哪里出了问题。我注意到,在执行计划中,它将属性命名为personid和personname,但您发布的查询通过名为id的属性查找节点。您确定用于绑定的属性为:person标签编制了索引吗?您可以在浏览器中键入:schema或在shell中键入schema来列出索引,并确认您在查询中使用的任何属性personid、id或:person标签中列出的任何属性。

这是来自冷缓存还是热缓存?您可能想在neo4j.properties中使用对象缓存设置,也可能是内存映射IO设置。您介意在查询中使用PROFILE命令并粘贴结果吗?是MATCH me:person-[:follows*2..2]->reco:person WHERE me.id=1000 RETURN me.id,countreco AS count做您想做的事吗?它执行得更快吗?您创建了索引吗?在:personid上创建索引。我没有更改默认设置。当缓存被加热超过10秒时,性能非常糟糕,我立即认为我的查询出了严重的问题。我确实有personid的索引。很抱歉,属性名称不一致。它应该是Personaid,而不是id。我在原来的帖子中输入了错误的原始查询。我将在使用WITH子句时试用你的建议。