统计和执行计划

当发出 Cypher 查询时,它会被编译成一个可以运行并回答查询的执行计划。Cypher 查询引擎使用有关数据库的可用信息,例如关于数据库中存在哪些索引和约束的模式信息。本页介绍如何在 Cypher 查询引擎中配置 Neo4j 统计信息收集和查询重新规划。

Neo4j 还使用有关数据库的统计信息来优化执行计划。有关更多信息,请参见 Cypher 手册 → 查询优化Cypher 手册 → 执行计划

配置统计信息收集

Cypher 查询规划器依赖于准确的统计信息来创建有效的计划。因此,随着数据库的发展,这些统计信息会保持最新。

对于 DBMS 中的每个数据库,Neo4j 收集以下统计信息并保持最新

对于图形实体
  • 具有特定标签的节点数量。

  • 按类型划分的边的数量。

  • 具有特定标签的节点之间按类型划分的边的数量。

每当您从节点设置或删除标签时,这些数字都会更新。

对于数据库模式
  • 每个索引的选择性。

为了生成选择性数字,Neo4j 在后台运行完整索引扫描。由于这可能是一个非常耗时的操作,因此只有在更改的数据达到指定的阈值时才会触发完整索引扫描。

自动统计信息收集

您可以通过配置以下设置来控制是否以及多久自动收集一次统计信息

参数名称 默认值 描述

db.index_sampling.background_enabled

true

启用自动(后台)索引采样。

db.index_sampling.update_percentage

5

触发给定索引采样所需的索引更新百分比占总索引大小的百分比。

手动统计信息收集

您可以使用内置过程 db.resampleIndex()db.resampleOutdatedIndexes() 手动触发索引重新采样。

db.resampleIndex()

触发指定索引的重新采样。

CALL db.resampleIndex("indexName")
db.resampleOutdatedIndexes()

触发所有过时索引的重新采样。

CALL db.resampleOutdatedIndexes()

配置执行计划的重新规划

执行计划被缓存,并且不会重新规划,直到用于生成计划的统计信息发生更改。

自动重新规划

您可以通过配置以下设置来控制重新规划对数据库更新的敏感程度

参数名称 默认值 描述

dbms.cypher.statistics_divergence_threshold

0.75

统计信息的阈值,高于该阈值,计划被认为是过时的。
当执行计划的底层统计信息的变化达到指定的阈值时,该计划被认为是过时的,并会重新规划。变化计算为 abs(a-b)/max(a,b)
这意味着 0.75 的值要求数据库的大小大约增加四倍才会发生重新规划。0 的值意味着只要统计信息发生变化且重新规划间隔过去,查询就会重新规划。

dbms.cypher.min_replan_interval

10s

两次查询重新规划执行之间的最短时间。在此时间之后,将评估图形统计信息,如果它们的变化超过了在 dbms.cypher.statistics_divergence_threshold 中设置的值,则重新规划查询。每次评估统计信息时,发散阈值都会降低,直到在大约 7 小时后降至 10%。这确保即使数据库变化适中,查询重新规划也会在足够长的时间间隔后发生。

手动重新规划

您可以使用以下内置过程手动强制数据库重新规划已经存在于缓存中的执行计划

db.clearQueryCaches()

清除所有查询缓存。不改变数据库统计信息。

CALL db.clearQueryCaches()
db.prepareForReplanning()

完全重新计算所有数据库统计信息,以便用于任何后续查询规划。

该过程会触发索引重新采样,等待其完成,并清除所有查询缓存。之后,查询将基于最新的数据库统计信息进行规划。

CALL db.prepareForReplanning()

您可以使用 Cypher 重新规划来指定是否要强制重新规划,即使该计划根据规划规则是有效的,或者如果您希望使用已经存在的有效计划,则完全跳过重新规划。

有关更多信息,请参见