我有以下查询
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上运行)
优化此查询的一些方法是什么,因为我认为节点和关系的数量不是很多。
答案 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;
当您尝试不同的查询时,可以在EXPLAIN
或PROFILE
前加上Cypher查询,以查看执行计划和数据点击次数。更多信息here.