本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
OpencyPherexplain
功能
OpencyPherexplain
功能是 Amazon Neptune 中的一个自助工具,可帮助您了解Neptune 引擎采用的执行方法。要调用 explain,您可以使用explain=
向 OpencyPher HTTPS 请求传递一个参数,其mode
mode
值可以是以下值之一:
-
static
— 在static
模式下,仅explain
打印查询计划的静态结构。它不实际运行查询。 -
dynamic
— 在dynamic
模式下,explain
还会运行查询,并包括查询计划的动态方面。其中可能包括流经运算符的中间绑定数量、传入绑定与传出绑定的比率以及每个运算符所花费的总时间。 -
details
— 在details
模式下,explain
打印动态模式下显示的信息以及其他详细信息,例如实际的 OpencyPher 查询字符串和连接运算符基础模式的估计范围数。
例如,使用POST
:
curl HTTPS://
server
:port
/openCypher \ -d "query=MATCH (n) RETURN n LIMIT 1;" \ -d "explain=dynamic"
或者,使用GET
:
curl -X GET \ "HTTPS://
server
:port
/openCypher?query=MATCH%20(n)%20RETURN%20n%20LIMIT%201&explain=dynamic"
Neptune 中 OpencyPherexplain
的局限性
OpencenyPHER 的当前版本存在以下限制:
解释计划目前仅适用于执行只读操作的查询。不支持执行任何类型突变的查询
CREATE
DELETE
MERGE
SET
,例如、、等。在future 版本中,特定计划的运算符和输出可能会发生变化。
OpencyPherexplain
输出中的 DFE 运算符
要使用 OpencyPherexplain
功能提供的信息,你需要了解有关 DFE 查询引擎工作原理的一些细节(DF E 是 Neptune 用来处理 OpencyPher 查询的引擎)。
DFE 引擎将每个查询转换为运算符管道。从第一个操作员开始,中间解决方案通过该操作流水线从一个操作员流向下一个操作员。解释表中的每一行都代表一个结果,直到评估为止。
可以出现在 DFE 查询计划中的运算符如下:
dfeApply — 对存储functor
在指定变量中的值执行参数部分中指定的函数
DFEBindRelation — 将具有指定名称的变量绑定在一起
DFEChunkLocalSubQuery — 这是一种非阻塞操作,用作正在执行的子查询的封装。
DFEDistinctColumn — 根据指定的变量返回输入值的不同子集。
DFEDistinctRelation — 根据指定的变量返回输入解的不同子集。
dfeDra in — 出现在子查询的末尾,用作该子查询的终止步骤。解决方案的数量记录为Units In
。 Units Out
始终为零。
DFELoopSubQuery — 这是一种非阻塞操作,用作子查询的封装,允许其重复运行以在循环中使用。
DFEOptionalJoin — 执行可选联接A OPTIONAL B ≡ (A JOIN B) UNION (A MINUS_NE B)
。这是一个阻止性操作。
DFEPipelineJoin — 根据pattern
参数定义的元组模式连接输入。
DFEPipelineScan-扫描数据库中的给定pattern
参数,无论是否对列使用给定过滤器。
DFERelationalJoin — 使用合并联接根据指定的模式键加入前一个运算符的输入。这是一个阻止性操作。
DFERelationalJoin — 使用合并联接根据指定的模式键加入前一个运算符的输入。这是一个阻止性操作。
dfeSubQuery — 此运算符出现在所有计划的开头,概括了计划中在 DFE 引擎上运行的部分,即 OpencyPher 的整个计划。
DFESymmetricHashJoin — 使用哈希联接根据指定的模式键加入前一个运算符的输入。这是一项非阻塞操作。
DFetee — 这是一个分支运算符,它向多个运算符发送相同的解集。
SolutionInjection— 出现在explain
输出中所有其他内容之前,Units Out
列中的值为 1。但是,它不起作用,实际上并没有向 DFE 引擎注入任何解决方案。
TermResolution— 出现在计划末尾,并将来自Neptune 引擎的物体转换为 OpencyPher 物体。
OpencyPherexplain
输出中的列
Neptune 在 OpencyPher 解释输出时生成的查询计划信息包含每行一个运算符的表。表具有以下几列:
Ou t #1(和 Ou t #2)— 该运算符下游的运算符的 ID。最多可以有两个下游运算符。
参数 — 操作员的任何相关细节。这包括输入架构、输出架构、模式(用于PipelineScan
和PipelineJoin
)等内容。
模式-描述基本操作员行为的标签。此列大部分为空 (-
)。一个例外是TermResolution
,模式可以是id2value_opencypher
,表示从 ID 到 OpencyPher 值的分辨率。
输入单位-作为输入传递给该运算符的解的数量。没有上游运算符的运算符DFEPipelineScan
,例如SolutionInjections
、和没有注入静态值的 aDFESubquery
,其值将为零。
Units Out — 此运算符输出时产生的解决方案数量。 DFEDrain
是一种特殊情况,其中记录了正在耗尽的解的数量,Units In
并且始终Units Out
为零。
时间 (ms) — 此运算符消耗的 CPU 时间,以毫秒为单位。
OpencyPher 的基本示例解释了输出
以下是 OpencyPherexplain
输出的基本示例。该查询是在空中航线数据集中对具有机场代码的节点进行单节点查找ATL
,该节点explain
使用默认 ASCII 输出格式的details
模式进行调用:
curl -d "query=MATCH (n {code: 'ATL'}) RETURN n" -k https://localhost:8182/openCypher -d "explain=details" ~ Query: MATCH (n {code: 'ATL'}) RETURN n ╔════╤════════╤════════╤═══════════════════╤════════════════════╤═════════════════════╤══════════╤═══════════╤═══════╤═══════════╗ ║ ID │ Out #1 │ Out #2 │ Name │ Arguments │ Mode │ Units In │ Units Out │ Ratio │ Time (ms) ║ ╠════╪════════╪════════╪═══════════════════╪════════════════════╪═════════════════════╪══════════╪═══════════╪═══════╪═══════════╣ ║ 0 │ 1 │ - │ SolutionInjection │ solutions=[{}] │ - │ 0 │ 1 │ 0.00 │ 0 ║ ╟────┼────────┼────────┼───────────────────┼────────────────────┼─────────────────────┼──────────┼───────────┼───────┼───────────╢ ║ 1 │ 2 │ - │ DFESubquery │ subQuery=subQuery1 │ - │ 0 │ 1 │ 0.00 │ 4.00 ║ ╟────┼────────┼────────┼───────────────────┼────────────────────┼─────────────────────┼──────────┼───────────┼───────┼───────────╢ ║ 2 │ - │ - │ TermResolution │ vars=[?n] │ id2value_opencypher │ 1 │ 1 │ 1.00 │ 2.00 ║ ╚════╧════════╧════════╧═══════════════════╧════════════════════╧═════════════════════╧══════════╧═══════════╧═══════╧═══════════╝ subQuery1 ╔════╤════════╤════════╤═══════════════════════╤══════════════════════════════════════════════════════════════════════════════════════════════════════════════╤══════╤══════════╤═══════════╤═══════╤═══════════╗ ║ ID │ Out #1 │ Out #2 │ Name │ Arguments │ Mode │ Units In │ Units Out │ Ratio │ Time (ms) ║ ╠════╪════════╪════════╪═══════════════════════╪══════════════════════════════════════════════════════════════════════════════════════════════════════════════╪══════╪══════════╪═══════════╪═══════╪═══════════╣ ║ 0 │ 1 │ - │ DFEPipelineScan │ pattern=Node(?n) with property 'code' as ?n_code2 and label 'ALL' │ - │ 0 │ 1 │ 0.00 │ 0.21 ║ ║ │ │ │ │ inlineFilters=[(?n_code2 IN ["ATL"^^xsd:string])] │ │ │ │ │ ║ ║ │ │ │ │ patternEstimate=1 │ │ │ │ │ ║ ╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 1 │ 2 │ - │ DFEChunkLocalSubQuery │ subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#9d84f97c-c3b0-459a-98d5-955a8726b159/graph_1 │ - │ 1 │ 1 │ 1.00 │ 0.04 ║ ╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 2 │ 3 │ - │ DFEProject │ columns=[?n] │ - │ 1 │ 1 │ 1.00 │ 0.04 ║ ╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 3 │ - │ - │ DFEDrain │ - │ - │ 1 │ 0 │ 0.00 │ 0.03 ║ ╚════╧════════╧════════╧═══════════════════════╧══════════════════════════════════════════════════════════════════════════════════════════════════════════════╧══════╧══════════╧═══════════╧═══════╧═══════════╝ subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#9d84f97c-c3b0-459a-98d5-955a8726b159/graph_1 ╔════╤════════╤════════╤══════════════════════╤════════════════════════════════════════════════════════════╤══════╤══════════╤═══════════╤═══════╤═══════════╗ ║ ID │ Out #1 │ Out #2 │ Name │ Arguments │ Mode │ Units In │ Units Out │ Ratio │ Time (ms) ║ ╠════╪════════╪════════╪══════════════════════╪════════════════════════════════════════════════════════════╪══════╪══════════╪═══════════╪═══════╪═══════════╣ ║ 0 │ 1 │ - │ DFESolutionInjection │ outSchema=[?n, ?n_code2] │ - │ 0 │ 1 │ 0.00 │ 0.02 ║ ╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 1 │ 2 │ 3 │ DFETee │ - │ - │ 1 │ 2 │ 2.00 │ 0.02 ║ ╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 2 │ 4 │ - │ DFEDistinctColumn │ column=?n │ - │ 1 │ 1 │ 1.00 │ 0.20 ║ ║ │ │ │ │ ordered=false │ │ │ │ │ ║ ╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 3 │ 5 │ - │ DFEHashIndexBuild │ vars=[?n] │ - │ 1 │ 1 │ 1.00 │ 0.04 ║ ╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 4 │ 5 │ - │ DFEPipelineJoin │ pattern=Node(?n) with property 'ALL' and label '?n_label1' │ - │ 1 │ 1 │ 1.00 │ 0.25 ║ ║ │ │ │ │ patternEstimate=3506 │ │ │ │ │ ║ ╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 5 │ 6 │ 7 │ DFESync │ - │ - │ 2 │ 2 │ 1.00 │ 0.02 ║ ╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 6 │ 8 │ - │ DFEForwardValue │ - │ - │ 1 │ 1 │ 1.00 │ 0.01 ║ ╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 7 │ 8 │ - │ DFEForwardValue │ - │ - │ 1 │ 1 │ 1.00 │ 0.01 ║ ╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 8 │ 9 │ - │ DFEHashIndexJoin │ - │ - │ 2 │ 1 │ 0.50 │ 0.35 ║ ╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢ ║ 9 │ - │ - │ DFEDrain │ - │ - │ 1 │ 0 │ 0.00 │ 0.02 ║ ╚════╧════════╧════════╧══════════════════════╧════════════════════════════════════════════════════════════╧══════╧══════════╧═══════════╧═══════╧═══════════╝
在顶层,SolutionInjection
出现在其他所有元素之前,出现 1 个单位。请注意,它实际上并没有注入任何解决方案。可以看到下一个运算符DFESubquery
有 0 个单位。
在顶SolutionInjection
层之后是DFESubquery
和TermResolution
运算符。 DFESubquery
封装了推送到 DFE 引擎的查询执行计划部分(对于 OpencyPher 查询,整个查询计划由 DFE 执行)。查询计划中的所有运算符都嵌套在subQuery1
所引用的内部DFESubquery
。唯一的例外是TermResolution
,它将内部 ID 具体化为完全序列化的 OpencyPher 对象。
所有推送到 DFE 引擎的运算符的名称都以DFE
前缀开头。如上所述,整个 OpencyPher 查询计划由 DFE 执行,因此,除最终运算符外,所有TermResolution
运算符均以开头DFE
。
在内部subQuery1
,可以有零个DFEChunkLocalSubQuery
或多个或DFELoopSubQuery
运算符封装在内存限制机制中执行的推送执行计划的一部分。 DFEChunkLocalSubQuery
这里SolutionInjection
包含一个用作子查询输入的内容。要在输出中查找该子查询的表,请在Arguments
列中搜索subQuery=
指定的 ograph URI
DFEChunkLocalSubQuery
rDFELoopSubQuery
运算符。
在中subQuery1
DFEPipelineScan
,使用ID
0 扫描数据库中的指定值pattern
。该模式会扫描一个实体,该实体code
将属性另存为所有标签的变量(您可以通过附加airport
到对特定标签进行?n_code2
过滤n:airport
)。该inlineFilters
参数显示了对等于属code
性的过滤ATL
。
接下来,DFEChunkLocalSubQuery
运算符连接包含的子查询的中间结果DFEPipelineJoin
。这样可以确保?n
它实际上是一个节点,因为之前的版本DFEPipelineScan
会扫描任何具有该code
属性的实体。