了解 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:X
-
语句 2:Y
-
语句 3:X
并且 Y 修改了 X 所使用的统计信息,则会在 messages.log 中看到上述消息。
例如,若语句 X 为 MATCH n RETURN n,语句 Y 为 CREATE (),则
-
语句 1 会导致 X 被放入查询缓存
-
语句 2 会导致 Y 被放入查询缓存
-
语句 3 将重新计划语句 X,因为已超过
dbms.cypher.min_replan_interval,且语句 Y 改变了语句 X 所使用的统计信息
此页面有帮助吗?