理解 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: 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 使用的统计数据。
本页有帮助吗?