知识库

了解 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 语句,它将会重新计划,因为它已经不再缓存中,当前缓存只包含第 2 到第 1001 条语句。

dbms.cypher.min_replan_interval - 默认值为 1 秒,描述 Cypher 语句在缓存中保留多长时间后才会被重新计划。例如,如果某条 Cypher 语句在 09:02:00 被计划,而 dbms.cypher.min_replan_interval 被设为 5 秒,则在 09:02:01 重新提交同一条语句不会导致重新计划。必须等到 09:02:06 才会再次满足重新计划的条件。

dbms.cypher.statistics_divergence_threshold - 默认值为 0.5(取值范围 0~1),描述针对该 Cypher 语句所涉及对象的统计信息变化百分比,超过该阈值将强制重新计划。例如,如果标签为 Movie 的节点中超过 50% 被修改,则运行涉及该标签的 Cypher 语句会导致重新计划;而不涉及 Movie 标签的语句则不会重新计划。

关于查询缓存,还应了解以下事项

  • 如果出现任何模式变更(如新增/删除索引或约束),所有查询计划会立即失效。

  • 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

如果随后按以下顺序发出两条 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 所使用的统计信息

© . This site is unofficial and not affiliated with Neo4j, Inc.