gpt4 book ai didi

performance - Neo4j 查询需要很长时间

转载 作者:行者123 更新时间:2023-12-04 10:55:13 25 4
gpt4 key购买 nike

我目前正在开发一个社交媒体网站,该网站在用户时间线方面完全相同,例如用户可以关注、创建、分享帖子、阻止、取消阻止等。因此,我们创建了 2 种类型的标签“用户"和 "发布"并有几个关系,如关注、阻止、私有(private)等。
目前,我们有大约 41000 个节点和 650000 个关系。

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

1 个主机和 2 个从机

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

MATCH (n:User {user_id:'12129bca-9b90-44c9-aae8-d80e61f9c342',is_active:'1'}),(p:Post{is_deleted:'0'}),(po:User{user_id:p.owner_id})
WHERE (p.post_type = '1' OR p.post_type = '4') WITH n,p,po
WHERE po.is_active='1' AND (n)-[:CREATED{own_status:'1'}]->(p) OR
(n)-[:FOLLOWS{follow_status:'1'}]->(:User{is_active:'1'})-[:CREATED{own_status:'1'}]->(p)
OR (n)-[:FOLLOWS{follow_status:'1'}]->(:Keyword{is_deleted:'0'})-[:KEYWORD]->(p)
WITH n,p,po
OPTIONAL MATCH (n)-[fr:FOLLOWS]->(po)
WHERE fr.follow_status='1' WITH p,n,po,fr
WHERE NOT ((n)-[:FOLLOWS{is_blocked:true}]->(po) OR (n)-[:FOLLOWS{is_mute:true}]->(po)) WITH p,n,po,fr
WHERE NOT (n)<-[:FOLLOWS{is_blocked:true}]-(po) WITH p,n,po,fr
WHERE (fr is not null and toInteger(po.is_private) <= 1 AND po.user_id <> n.user_id)
OR (toInteger(po.is_private) <= 1 AND po.user_id = n.user_id)
OR (toInteger(po.is_private) = 0 AND po.user_id <> n.user_id) WITH p,n,po
RETURN p,po,SIZE(()-[:LIKED]->(p)) as likecount,
SIZE((n)-[:LIKED]->(p)) as likestatus,count(*) as postcount
ORDER BY p.created_at DESC
SKIP 0 LIMIT 10

此查询需要 10 多秒。这太高了

这是上述查询的简介

enter image description here

这是索引列表
enter image description here

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

最佳答案

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

当前编写的查询的第一个匹配语句查找特定用户,然后是具有属性 is_deleted:'0' 的所有 Post 节点,然后是连接到任何 Post 节点的所有 User 节点。以这种方式搜索会在第一个中间 Expand(All) 中为您提供比数据库中的节点数 (41,000) 更多的数据库命中 (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 节.

关于performance - Neo4j 查询需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59246905/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com