Neo4j查询花费很长时间

时间:2019-12-09 10:29:55

标签: performance neo4j cypher query-optimization py2neo

我目前正在一个社交媒体网站上工作,该网站在用户时间轴方面完全相同,例如用户可以关注,创建,共享帖子,屏蔽,取消屏蔽等。为此,我们创建了两种类型的标签为“用户”和“发布”,并具有以下关系,例如关注,阻止,私有等。 目前,我们大约有41000个节点和650000个关系。

硬件配置: 8 GB内存 2芯 50 GB硬盘

1个主人和2个奴隶

并使用以下查询获取用户的时间轴

function writeToLog($data, $title = '') {
 $log = "\n------------------------\n";
 $log .= date("Y.m.d G:i:s") . "\n";
 $log .= (strlen($title) > 0 ? $title : 'DEBUG') . "\n";
 $log .= print_r($data, 1);
 $log .= "\n------------------------\n";
 file_put_contents(getcwd() . '/hook.log', $log, FILE_APPEND);
 return true;
}

此查询耗时超过10秒。太高了

以下是上述查询的个人资料

enter image description here

这是索引列表 enter image description here

有人可以建议我在哪里做错了吗?

1 个答案:

答案 0 :(得分:2)

如果您想获取用户的时间轴,我认为您应该从特定用户开始,然后通过您感兴趣的关系连接到其他节点。当前查询没有利用模式匹配或图数据库的连接性质。

当前编写的查询的第一个match语句先找到一个特定用户,然后找到所有具有is_deleted:'0'属性的Post节点,然后再找到连接到任何Post节点的所有User节点。通过这种方式进行搜索,与数据库中的节点数(41,000)相比,在第一个中间Expand(All)中数据库命中数(54,984)更多。

最优化此查询的地方是将搜索集中在单个用户上,然后使用以下关系从那里扩展:

MATCH (n:User {user_id:'12129bca-9b90-44c9-aae8-d80e61f9c342',is_active:'1'})-[r]-(p:Post{is_deleted:'0'})

这将匹配用户以及通过关系连接到该用户的所有合格帖子。请注意,如果用户没有连接到任何合格的帖子,则即使该用户确实存在于数据库中也不会有任何匹配项。

如果只想包括某些关系类型,则可以在第一个MATCH语句中指定为这种关系类型:

MATCH (n:User {user_id:'12129bca-9b90-44c9-aae8-d80e61f9c342',is_active:'1'})-[r:CREATED|FOLLOWS|KEYWORD]-(p:Post{is_deleted:'0'})

或者您可以像这样将其放在WHERE子句中:

MATCH (n:User {user_id:'12129bca-9b90-44c9-aae8-d80e61f9c342',is_active:'1'})-[r]-(p:Post{is_deleted:'0'})
WHERE type(r) in ['CREATED', 'FOLLOWS' , 'KEYWORD']

我没有遵循所有的条件语句(我认为将其转换为模式匹配后,您也许可以删除其中的一些条件语句),但是一旦有了初始模式,就可以添加所需的任何条件语句。示例:

WHERE (p.post_type = '1' OR p.post_type = '4')
  AND (r.own_status = '1' OR r.follow_status = '1')
  AND NOT r.is_blocked = true

有关模式匹配的更多信息,请查看Neo4j Cypher Manual的2.9节。