【问题标题】:NEO4J - Optional query very slowNEO4J - 可选查询非常慢
【发布时间】:2021-06-15 00:45:09
【问题描述】:

我是 Neo4J 的新手,我有以下疑问,我怎样才能让它更快?真的需要很长时间

MATCH (vintage:Vintage)-[:MADE_FROM]->(wine:Wine)
OPTIONAL MATCH (vintage)-[:DESIGNATED_BY]->(app:Appellation)
OPTIONAL MATCH (vintage)-[:RANKED]->(ranking:Ranking)
OPTIONAL MATCH (vintage)-[:HAS_NOTE]->(note:Note)<-[:REVIEWS]-(reviewer:Reviewer)
WITH reviewer, note, app, wine, vintage ORDER BY vintage.code ASC, vintage.year DESC
RETURN { vintages: collect({ uid: vintage.uid, year: vintage.year,  
      cv: vintage.referencePrice})[10 * (1 - 1)..10 * 1], total: size(collect(vintage)) } as vintage

Explain model

【问题讨论】:

  • 您正在执行没有任何起始节点的数据库扫描,因此预计会很慢。
  • 请提供 PROFILE 计划,它将显示操作之间的行信息。也请展开计划的所有内容。

标签: performance neo4j graphql match optional


【解决方案1】:

有点奇怪,您获得了所有这些可选信息(应用程序、排名、注释、评论者),但您并没有对它做任何事情。你没有返回任何这些,你只是返回了年份的信息。

如果你不会使用它,请不要匹配它。

但是,如果您的意图是确保每个模式至少存在一个这样的路径,请为这些使用 WHERE 子句,如果某些 OPTIONAL MATCH 存在多个路径,这也将避免交叉乘积问题。

但是由于您使用的是 OPTIONAL MATCHes,因此您似乎不希望它们出现在图表中或不存在来控制是否返回年份。因此,它们没有任何用途,只会让您的查询变慢。您似乎唯一的硬性要求是 :Vintage 由 :Wine 制成(尽管如果所有 :Vintages 均由 :Wine 制成,您也可以删除该部分)。我们会保留它并删除其他的。

另外,您对总年份的计算也不正确。由于您使用的是 OPTIONAL MATCHes,因此您并不关心满足那里模式的年份,因此我们可以在 MATCHING 到各个节点之前对年份进行总计。

最后不清楚您只是在寻找节点的子集,因此我们可以取消列表切片方法并使用 SKIP 和 LIMIT 代替。这也可能是您的查询需要这么长时间的原因......它正在计算所有年份信息,但您最后只取了一部分,所以您做的很多工作只是在结束。

试试这个:

MATCH (vintage:Vintage)
WHERE (vintage)-[:MADE_FROM]->(:Wine)
WITH count(vintage) as total

MATCH (vintage:Vintage)
WHERE (vintage)-[:MADE_FROM]->(:Wine)
WITH total, vintage
ORDER BY vintage.code ASC, vintage.year DESC
SKIP 0
LIMIT 10
WITH total, collect({ uid: vintage.uid, year: vintage.year, cv: vintage.referencePrice}) as vintages
RETURN { vintages:vintages, total:total} as vintage

如果这些 OPTIONAL MATCHes 有目的,请在 cmets 中解释,我会看看如何修改查询来处理它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    相关资源
    最近更新 更多