知识库

理解 Neo4j 查询计划缓存

本文基于 Neo4j 2.3.2 的行为。查询计划缓存由三个参数控制,这些参数在 conf/neo4j.properties 文件中定义,详细信息请参见此处

控制 Cypher 语句是否被计划/重新计划的三个参数是:

  • query_cache_size

  • dbms.cypher.min_replan_interval

  • dbms.cypher.statistics_divergence_threshold

query_cache_size - 默认为 1000,表示缓存中记录的查询计划数量。例如,如果您重新启动 Neo4j 并运行 1001 个唯一的 Cypher 语句,每个语句都将被计划,最后 1000 个语句将被记录在查询计划缓存中。如果您随后重新运行第一个 Cypher 语句,它将因为不在查询缓存中而被重新计划,因为目前缓存中只有 Cypher 语句 2 到 1001。

dbms.cypher.min_replan_interval - 默认为 1 秒,描述 Cypher 语句在缓存中存在的时间,在此时间后它将被重新计划。例如,如果一个 Cypher 语句在 09:02:00 被计划,并且 dbms.cypher.min_replan_interval 被定义为 5 秒,那么在 09:02:01 重新提交相同的 Cypher 语句不会导致重新计划。直到 09:02:06,该 Cypher 语句才符合重新计划的条件。

dbms.cypher.statistics_divergence_threshold - 默认为 0.5(值在 0 和 1 之间),描述与 Cypher 相关对象统计信息变化的百分比,这会强制重新计划。例如,如果带有标签 Movie 的节点有超过 50% 发生变化,那么运行涉及此标签的 Cypher 语句将导致重新计划。然而,运行不涉及标签 Movie 的 Cypher 语句则不会导致重新计划。

此外,关于查询缓存,您还应注意以下几点:

  • 如果有任何模式更改,无论是通过添加/删除索引还是约束,所有查询计划都会立即失效。

  • Cypher 支持带参数的查询。这意味着开发人员不必通过构建字符串来创建查询。

  • 此外,这也使得 Cypher 更容易缓存执行计划。

更多详情请参见此处

此外,如果您在 graph.db/messages.log 中看到类似以下消息:

2016-03-08 09:43:16.854+0000 INFO [o.n.c.i.ServerExecutionEngine] Discarded stale query from the query cache: CYPHER 2.3 match n return n ... ... ...

这表示先前在查询计划缓存中但随后被重新计划的计划。如果查询计划之前从未生成过,则不会遇到此消息。

要出现此消息,必须满足以下条件:

a) 再次看到查询之间至少发生了一次事务
b) 至少过去了 dbms.cypher.min_replan_interval
c) 查询使用的统计数据有超过 dbms.cypher.statistics_divergence_threshold 百分比发生变化(已编辑)

例如,要生成上述消息,可以定义:

dbms.cypher.min_replan_interval=0s
dbms.cypher.statistics_divergence_threshold=0

如果您随后按以下顺序发出 2 个 Cypher 语句 X 和 Y:

  1. 语句 1: X

  2. 语句 2: Y

  3. 语句 3: X

并且 Y 修改了 X 使用的统计数据,那么我们将在 messages.log 中看到上述消息。

例如,如果语句 X 是 MATCH n RETURN n 并且语句 Y 是 CREATE (),那么

  1. 语句 1 导致 X 被放入查询缓存

  2. 语句 2 导致 Y 被放入查询缓存

  3. 语句 3 将重新计划语句 X,因为已超过

dbms.cypher.min_replan_interval 设定的时间,并且语句 Y 改变了语句 X 使用的统计数据。

© . All rights reserved.