【问题标题】:Cypher paged-listing query optimizationCypher 分页列表查询优化
【发布时间】:2020-11-19 12:54:08
【问题描述】:

我们在 Neo4j 数据库中有以下数据模型。 标签为 Post 的节点,以及标签为 User

的节点

PostUser之间的关系是(Post)-[:POSTED_BY]->(User)。它表示帖子是由给定用户创建的。

在 Post 节点上,有一个名为 sort_order 的属性,它给出了应该检索 post 节点的顺序。 sort_order唯一的索引支持的;在架构中强制执行唯一约束。

在列表请求中,我需要获取由sort_order 排序的给定用户的帖子,并且在 10 页中(例如)

根据Neo4j Documentation,由于节点已经根据所选属性sort_order的索引进行了排序,因此规划器跳过了排序操作。这限制了选定页面大小完成查询所需的数据库命中和时间。这完全适用于这样的查询:

MATCH (post:Post)
where post.sort_order > 0
return post
order by post.sort_order desc
limit 10

如果给出提示post.sort_order > 0

一旦我需要检索给定用户的帖子,查询将获取与所选用户相关的所有帖子节点,在内存中对它们进行排序,并返回当前页面(10 条记录)。在分析以下所需查询后,它似乎忽略了索引。

MATCH (post:Post)-[:IN]->(user:User {id: 3})
where post.sort_order > 0
return post
order by post.sort_order desc
limit 10

查询或数据模型中是否存在任何隐藏问题?

或者,如果可以对查询、数据模型或索引进行任何优化。

使用的neo4j版本是3.5.23

【问题讨论】:

标签: neo4j cypher graph-databases


【解决方案1】:

Cypher 规划器可能确定(使用服务器的数据库统计信息)通过查找 User 节点(希望您有一个 :User(id) 索引来帮助)执行最后一个查询通常更有效,得到其相关的Post 节点,然后排序。

如果您成功地强制规划器改用您的 :Post(sort_order) 索引,那么执行效率可能会低得多。这是因为查询仍然需要为(大概几乎)每个Post 获取和评估相关的User 节点。

【讨论】:

  • 是的,这听起来合乎逻辑。但是,如果一个用户节点连接了数千个 Post 节点,那么这两种方式在速度和内存方面都会很昂贵。对于给定的用户节点,有什么建议可以更好地对帖子节点进行分页吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多