为什么 Neo4j 查询<-[*]-(o) cause a timeout, whereas (o)-[*]->能按预期工作?

问题描述 投票:0回答:1

我正在使用 Neo4j 并遇到特定查询结构的超时问题。我有两个查询看起来非常相似,但在性能方面产生不同的结果。

以下是疑问:

  1. 这个按预期工作并返回所需的结果:

    MATCH (selected_method:Method{name:$neodash_method_name, class_name:$neodash_class_name, module_name:$neodash_module_name})
    MATCH (others:Method)-[all*]->(selected_method)
    RETURN *
    
  2. 但是,以下查询超时:

    MATCH (selected_method:Method{name:$neodash_method_name, class_name:$neodash_class_name, module_name:$neodash_module_name})
    MATCH (selected_method)<-[all*]-(others:Method)
    RETURN *
    

我希望这两个查询具有相似的性能。

发生的事情有什么解释吗?

我使用了

EXPLAIN
命令,它为两个查询返回了相同的执行计划:

Planner COST

Runtime PIPELINED

Runtime version 5.20

Batch size 1024

+------------------------+----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| Operator               | Id | Details                                                                                              | Estimated Rows | Pipeline            |
+------------------------+----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| +ProduceResults        |  0 | all, others, selected_method                                                                         |      109067277 |                     |
| |                      +----+------------------------------------------------------------------------------------------------------+----------------+                     |
| +VarLengthExpand(Into) |  1 | (others)-[all*]->(selected_method)                                                                   |      109067277 | Fused in Pipeline 3 |
| |                      +----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| +CartesianProduct      |  2 |                                                                                                      |          67222 | In Pipeline 2       |
| |\                     +----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| | +NodeByLabelScan     |  3 | others:Method                                                                                        |          23190 | In Pipeline 1       |
| |                      +----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| +Filter                |  4 | (selected_method.name = $neodash_method_name AND selected_method.class_name = $neodash_class_name AN |              3 |                     |
| |                      |    | D selected_method.module_name = $neodash_module_name)                                                |                |                     |
| |                      +----+------------------------------------------------------------------------------------------------------+----------------+                     |
| +NodeByLabelScan       |  5 | selected_method:Method                                                                               |          23190 | Fused in Pipeline 0 |
+------------------------+----+------------------------------------------------------------------------------------------------------+----------------+---------------------+

Total database accesses: ?
Planner COST

Runtime PIPELINED

Runtime version 5.20

Batch size 1024

+------------------------+----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| Operator               | Id | Details                                                                                              | Estimated Rows | Pipeline            |
+------------------------+----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| +ProduceResults        |  0 | all, others, selected_method                                                                         |      109067277 |                     |
| |                      +----+------------------------------------------------------------------------------------------------------+----------------+                     |
| +VarLengthExpand(Into) |  1 | (selected_method)<-[all*]-(others)                                                                   |      109067277 | Fused in Pipeline 3 |
| |                      +----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| +CartesianProduct      |  2 |                                                                                                      |          67222 | In Pipeline 2       |
| |\                     +----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| | +NodeByLabelScan     |  3 | others:Method                                                                                        |          23190 | In Pipeline 1       |
| |                      +----+------------------------------------------------------------------------------------------------------+----------------+---------------------+
| +Filter                |  4 | (selected_method.name = $neodash_method_name AND selected_method.class_name = $neodash_class_name AN |              3 |                     |
| |                      |    | D selected_method.module_name = $neodash_module_name)                                                |                |                     |
| |                      +----+------------------------------------------------------------------------------------------------------+----------------+                     |
| +NodeByLabelScan       |  5 | selected_method:Method                                                                               |          23190 | Fused in Pipeline 0 |
+------------------------+----+------------------------------------------------------------------------------------------------------+----------------+---------------------+

Total database accesses: ?

我也尝试过使用不同的运行时设置,但第二个查询始终导致超时。

neo4j cypher query-optimization
1个回答
0
投票

这两个查询代表相同的事物,并且会产生相同的结果。我们知道写作(s)<-[*]-(o) means the same thing as writing (o)-[*]->(s)。正如您所写,查询计划是相同的,具有相同的运算符和基数估计。

但是,获得结果的过程可能有所不同。您会看到 VarLengthExpand(Into) 运算符的详细信息因模式写入的方向而异(就像在查询中一样)。当进行 VarLength 扩展时,查询运行时必须决定从一个节点开始扩展,并且从哪里开始可能取决于它的写入顺序(至少我认为可以)。根据图形结构,从一个开始时可能是一个快速操作,但从另一个开始时可能会很大。

想象一下,如果 (o) 仅与 (s) 有单一连接,而 (s) 与所有事物都有连接。如果你现在从 (o) 开始,你将遵循一个关系,找到 (s) 并知道你已经完成了,而如果你从 (s) 开始,你将必须遍历所有内容,然后才能知道它与 (o) 仅有一个连接).

现在,还有更多内容,例如图的统计数据和基数估计,在本例中 (s) 和 (o) 之间非常不同。所以我不能肯定地说情况就是如此,但是编写查询的顺序会影响运行所需的时间,或者即使它是可解决的,即使最终结果是相同的。

现在,尽管如此,这也可能是由于查询执行中的某些问题造成的。在不知道图表是什么样子的情况下,它似乎应该知道最好从哪里开始。看起来你在 5.20 上运行,我建议你尝试升级到最新版本(目前是 5.25.1)并尝试那里,它可能会解决它(如果你在 Aura 上,你已经在 5.25 上) .1 因此您无需执行任何操作,只需重试即可)。

© www.soinside.com 2019 - 2024. All rights reserved.