Amazon Neptune 中的查询计划缓存
查询提交至 Neptune 时,查询字符串会被解析、优化并转换为查询计划,然后由引擎执行。应用程序通常依赖通用查询模式,这些模式会通过传入不同参数值来实例化。查询计划缓存可以通过缓存查询计划,避免对此类重复的模式进行解析和优化,从而降低整体延迟。
查询计划缓存可用于 openCypher 查询,包括非参数化查询或参数化查询。READ(包括 HTTP 和 Bolt)支持该功能。OC 突变查询不支持该功能。Gremlin 或 SPARQL 查询不支持该功能。
如何强制启用或禁用查询计划缓存
默认情况下,查询计划缓存处于启用状态,用于低延迟参数化查询。仅当延迟低于 100 毫秒的阈值时,系统才会缓存参数化查询的计划。查询级别的查询提示 QUERY:PLANCACHE 可以在每个查询(无论是否参数化)的基础上覆盖此行为。它需要与 USING 子句一起使用。该查询提示接受 enabled 或 disabled 作为值。
# Forcing plan to be cached or reused % curl -k https://<endpoint>:<port>/opencypher \ -d "query=Using QUERY:PLANCACHE \"enabled\" MATCH(n) RETURN n LIMIT 1" % curl -k https://<endpoint>:<port>/opencypher \ -d "query=Using QUERY:PLANCACHE \"enabled\" RETURN \$arg" \ -d "parameters={\"arg\": 123}" # Forcing plan to be neither cached nor reused % curl -k https://<endpoint>:<port>/opencypher \ -d "query=Using QUERY:PLANCACHE \"disabled\" MATCH(n) RETURN n LIMIT 1"
如何确定计划是否已缓存
对于 HTTP READ,如果已提交查询且计划已缓存,则 explain 将显示与查询计划缓存相关的详细信息。
% curl -k https://<endpoint>:<port>/opencypher \ -d "query=Using QUERY:PLANCACHE \"enabled\" MATCH(n) RETURN n LIMIT 1" \ -d "explain=[static|details]" Query: <QUERY STRING> Plan cached by request: <REQUEST ID OF FIRST TIME EXECUTION> Plan cached at: <TIMESTAMP OF FIRST TIME EXECUTION> Parameters: <PARAMETERS, IF QUERY IS PARAMETERIZED QUERY> Plan cache hits: <NUMBER OF CACHE HITS FOR CACHED PLAN> First query evaluation time: <LATENCY OF FIRST TIME EXECUTION> The query has been executed based on a cached query plan. Detailed explain with operator runtime statistics can be obtained by running the query with plan cache disabled (using HTTP parameter planCache=disabled).
使用 Bolt 时,不支持解释特征。
驱逐
当达到缓存生存时间(TTL)或缓存查询计划的最大数量时,查询计划将被驱逐。当查询计划被命中时,TTL 会刷新。默认值为:
-
1000 – 每个实例可以缓存的最大计划数。
-
TTL – 30 万毫秒或 5 分钟。缓存命中会重新启动 TTL,并将其重置回 5 分钟。
导致计划无法缓存的条件
在以下条件下,系统不会使用查询计划缓存:
-
使用查询提示
QUERY:PLANCACHE "disabled"提交查询。您可以重新运行查询并删除QUERY:PLANCACHE "disabled"以启用查询计划缓存。 -
提交的查询不是参数化查询且不包含提示
QUERY:PLANCACHE "enabled"。 -
如果查询评估时间大于延迟阈值,则该查询不会被缓存,并且被视为长时查询,不会使用查询计划缓存。
-
查询包含不返回任何结果的模式。
-
例如
MATCH (n:nonexistentLabel) return n(当具有指定标签的节点为零时)。 -
例如带有
parameters={"param": "abcde"}的MATCH (n {name: $param}) return n(当包含name=abcde的节点为零时)。
-
-
查询参数是复合类型,例如
list或map。curl -k https://<endpoint>:<port>/opencypher \ -d "query=Using QUERY:PLANCACHE \"enabled\" RETURN \$arg" \ -d "parameters={\"arg\": [1, 2, 3]}" curl -k https://<endpoint>:<port>/opencypher \ -d "query=Using QUERY:PLANCACHE \"enabled\" RETURN \$arg" \ -d "parameters={\"arg\": {\"a\": 1}}" -
查询参数是一个未参与数据加载或数据插入操作的字符串。例如,如果运行
CREATE (n {name: "X"})以插入"X",则RETURN "X"会被缓存,而RETURN "Y"不会被缓存,因为"Y"尚未插入且不在数据库中。