优化Cypher查询 - Neo4j

时间:2015-11-13 21:52:12

标签: neo4j query-optimization cypher graph-databases

我有以下查询

MATCH(User1) - [:VIEWED] - >(页面)< - [:VIEWED] - (User2)

将User1.userId,User2.userId,count(page)返回为cnt

它是一个相对简单的查询,用于查找用户之间的共页面视图计数。 它太慢了,我不得不在一段时间后终止它。

详细

用户包含大约150k节点 页面包含大约180k节点

用户-VIEWS->页面有大约380k关系

用户有7个属性,而Page有5个属性。

User和Page分别在UserId和PageId上编入索引。

堆大小为512mb(试图在1g上运行)

优化此查询的一些方法是什么,因为我认为节点和关系的数量不是很多。

1 个答案:

答案 0 :(得分:1)

使用标签

始终在模式中使用Node labels

MATCH (u1:User)-[:VIEWED]->(p:Page)<-[:VIEWED]-(u2:User)
RETURN u1.userId, u2.userId, count(p) AS cnt;

不要在重复的用户对上匹配

将对所有用户对(共享已查看的页面)执行此查询两次。每个用户都将映射到User1,然后每个用户也将映射到User2。限制这个:

MATCH (u1:User)-[:VIEWED]->(p:Page)<-[:VIEWED]-(u2:User)
WHERE id(u1) > id(u2)
RETURN u1.userId, u2.userId, count(p) AS cnt;

查询特定用户

如果您可以绑定模式的任何一侧,查询将更快。您是否需要为所有用户对执行此查询?相对于单个用户执行它是否有意义?例如:

MATCH (u1:User {name: "Bob"})-[:VIEWED]->(p:Page)<-[:VIEWED]-(u2:User)
WHERE NOT u1=u2
RETURN u1.userId, u2.userId, count(p) AS cnt;

当您尝试不同的查询时,可以在EXPLAINPROFILE前加上Cypher查询,以查看执行计划和数据点击次数。更多信息here.