Neo4j分页查询优化

wljmcqd8  于 2023-01-25  发布在  其他
关注(0)|答案(1)|浏览(372)

我有两个查询,一个是通常编写分页查询的方式

MATCH (e:Event), (e)--(l:Place), (e)--(u:User)
OPTIONAL MATCH (e)--(ls:LiveStream)
WITH e {
  .*,
  _id: id(e),
  location: properties(l),
  livestream: properties(ls),
  photos: [(e)--(p:Photo) | p.url],
  createdAt: toString(e.createdAt),
  tags: [(e)--(t:Tag) | properties(t)]
} AS event
RETURN event
SKIP $page * $size
LIMIT $size

下一个在Event节点上使用早期的SKIP AND LIMIT

MATCH (e:Event)
WITH e SKIP $page * $size LIMIT $size
MATCH (e)--(l:Place), (e)--(u:User)
OPTIONAL MATCH (e)--(ls:LiveStream)
WITH e {
  .*,
  _id: id(e),
  location: properties(l),
  livestream: properties(ls),
  photos: [(e)--(p:Photo) | p.url],
  createdAt: toString(e.createdAt),
  tags: [(e)--(t:Tag) | properties(t)]
} AS event
RETURN event

如果SKIP的值为0,LIMIT的值为10,则第一个查询计划器的结果为

而第二查询计划器产生

第一个似乎遍历了整个数据库,而第二个只从10个Event节点开始。
这两种方法的优点和缺点是什么,尤其是当数据库中的数据量增加时。

z31licg0

z31licg01#

第二个查询:

MATCH (e:Event)
WITH e SKIP $page * $size LIMIT $size
MATCH (e)--(l:Place), (e)--(u:User)
OPTIONAL MATCH (e)--(ls:LiveStream)
WITH e {
  .*,
  _id: id(e),
  location: properties(l),
  livestream: properties(ls),
  photos: [(e)--(p:Photo) | p.url],
  createdAt: toString(e.createdAt),
  tags: [(e)--(t:Tag) | properties(t)]
} AS event
RETURN event

是首选的方法,因为它只遍历10个事件节点的关系,无论是链接到Place、User、Photo还是Tag。因此,此查询遍历的图非常小。这里唯一的警告是,您使用MATCH查找与PlaceUser的链接。因此,如果10个事件节点中有任何一个未链接到任何PlaceUser,则将被过滤掉。
第一个查询遍历所有事件节点的关系,然后分页,这使得大量的图形遍历和数据转换操作变得无用,因此性能不高。
随着图形大小的增加,第二个查询是可行的。另外,我注意到您没有在任何地方使用User节点,所以如果它们是多余的,您可能需要删除它。

相关问题