本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
openCypher explain 特征
openCypher explain 特征是 Amazon Neptune 中的一种自助式工具,可帮助您了解 Neptune 引擎所采用的执行方法。要调用 explain,您需要使用 explain= 向 openCypher HTTPS 请求传递一个参数,其中 modemode 值可以是以下值之一:
-
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 中 openCypher explain 的限制
openCypher Explain 的当前版本存在以下限制:
Explain 计划目前仅适用于执行只读操作的查询。不支持执行任何类型的突变(例如
CREATE、DELETE、MERGE、SET等)的查询。特定计划的运算符和输出可能会在将来版本中发生变化。
openCypher explain 输出中的 DFE 运算符
要使用 openCypher explain 特征提供的信息,您需要了解有关 DFE 查询引擎工作原理的一些详细信息(DFE 是 Neptune 用来处理 openCypher 查询的引擎)。
DFE 引擎将每个查询转换到一个运算符管道中。从第一个运算符开始,中间解将通过这个运算符管道从一个运算符流到下一个运算符。Explain 表中的每一行表示一个结果(截至到评估点)。
可以出现在 DFE 查询计划中的运算符如下所示:
DFEApply— 对存储在指定变量中的值执行参数部分中指定的函数
DFEBind关系-将具有指定名称的变量绑定在一起
DFEChunkLocalSubQuery— 这是一种非阻塞操作,充当正在执行的子查询的封装器。
DFEDistinct列-根据指定的变量返回输入值的不同子集。
DFEDistinct关系-根据指定的变量返回输入解决方案的不同子集。
DFEDrain— 出现在子查询的末尾,用作该子查询的终止步骤。解的数量记录为 Units In。Units Out 始终为零。
DFEForward值 — 将所有输入块直接复制为输出块,以传递给其下游运算符。
DFEGroupByHashIndex— 根据先前计算的哈希索引(使用运算)对输入解执行分组DFEHashIndexBuild运算。作为输出,给定输入通过包含每个输入解的组键的列进行扩展。
DFEHashIndexBuild— 在一组变量上建立哈希索引作为副作用。此哈希索引通常会在以后的操作中重复使用。有关此哈希索引可能用在何处,请参阅 DFEHashIndexJoin 或 DFEGroupByHashIndex。
DFEHashIndexJoin— 根据先前构建的哈希索引对传入的解决方案执行联接。有关此哈希索引可能在何处构建,请参阅 DFEHashIndexBuild。
DFEJoinE x ists — 采用左手和右手输入关系,并保留左侧关系中具有相应值的值,这些值由给定联接变量定义。
- 这是一种非阻塞操作,它充当子查询的包装器,允许重复运行子查询以在循环中使用。
DFEMergeChunks — 这是一种阻塞操作,它将来自其上游运算符的区块组合成单个解决方案块,然后传递给其下游运算符(相反)。DFESplitChunks
DFEMinus— 采用左手和右手输入关系,并保留左侧关系中在给定连接变量定义的右关系中没有相应值的值。如果两个关系中的变量没有重叠,则此运算符只返回左侧输入关系。
DFENotE x ists — 采用左手和右手输入关系,并保留左侧关系中在给定联接变量定义的右关系中没有相应值的值。如果两个关系中的变量没有重叠,则此运算符会返回空关系。
DFEOptional联接-执行左外联接(也称为可选联接):左侧的解决方案如果右侧至少有一个加入伙伴,则按原样转发来自左侧的解决方案,而右侧没有加入伙伴的解决方案则按原样转发。这是一项阻止操作。
DFEPipelineJo in — 根据pattern参数定义的元组模式连接输入。
DFEPipelineRangeCount— 计算与给定模式匹配的解数,并返回包含计数值的单一单元解。
DFEPipeline扫描-扫描数据库中的给定pattern参数,无论是否对列使用给定过滤器。
DFEProject— 获取多个输入列并仅投影所需的列。
DFEReduce— 对指定变量执行指定的聚合函数。
DFERelationalJo in — 使用合并联接根据指定的模式键连接前一个运算符的输入。这是一项阻止操作。
DFERouteChunks — 从其单个传入边缘获取输入块,然后沿着其多个传出边缘路由这些块。
DFESelect行-此运算符有选择地从其左侧输入关系解中提取行,以转发到其下游运算符。根据运算符右侧输入关系中提供的行标识符选择的行。
DFESerialize— 将查询的最终结果序列化为 JSON 字符串序列化,将每个输入解决方案映射到相应的变量名称。对于节点和边缘结果,这些结果将序列化为实体属性和元数据的映射。
DFESort— 获取输入关系并根据提供的排序键生成排序关系。
DFESplitByGroup— 将来自一个传入边的每个输入块拆分为较小的输出块,这些块对应于行组,行组由 IDs 来自另一个传入边的相应输入块的行标识。
DFESplitChunks — 将每个输入块拆分为较小的输出块(相反)。DFEMergeChunks
DFEStreamingHashIndexBuild— 直播版本的DFEHashIndexBuild.
DFEStreamingGroupByHashIndex— 直播版本的DFEGroupByHashIndex.
DFESubquery— 该运算符出现在所有计划的开头,它封装了计划中在 DFE 引擎上运行的部分,这是 OpenCypher 的整个计划。
DFESymmetricHashJoin— 使用哈希联接根据指定的模式键连接前一个运算符的输入。这是一个非阻止操作。
DFESync— 此运算符是支持非阻塞计划的同步运算符。它从两个传入边缘获取解,然后将这些解转发到相应的下游边缘。出于同步目的,可以对其中一个边缘的输入进行内部缓冲。
DFETee— 这是一个分支运算符,它向多个运算符发送相同的解决方案集。
DFETerm分辨率-对其输入执行本地化或全局化操作,生成分别包含本地化或全球化标识符的列。
- 将输入列中的值列表作为单个元素展开到输出列。
DFEUnion— 采用两个或多个输入关系,并使用所需的输出架构生成这些关系的并集。
SolutionInjection— 显示在 explain 输出中的其他所有内容之前,在 Units Out 列中的值为 1。但是,它不起作用,实际上并没有向 DFE 引擎注入任何解。
TermResolution— 出现在计划末尾,将海王星引擎中的对象转换为 OpenCypher 对象。
openCypher explain 输出中的列
Neptune 作为 openCypher explain 输出生成的查询计划信息包含每行具有一个运算符的表。此表包含以下各列:
ID – 计划中此运算符的数字 ID。
Out #1(和 Out #2)– 此运算符下游的运算符的 ID。最多可以有两个下游运算符。
Name – 此运算符的名称。
Arguments – 运算符的任何相关详细信息。这包括如输入架构、输出架构、模式(对于 PipelineScan 和 PipelineJoin)等。
Mode – 描述基本运算符行为的标签。此列一般为空白 (-)。一个例外是 TermResolution,其中模式可以是 id2value_opencypher,表示从 ID 到 openCypher 值的解。
Units In – 作为输入传递给该运算符的解的数量。没有上游运算符的运算符(例如 DFEPipelineScan、SolutionInjections 和未注入静态值的 DFESubquery)的值为零。
Units Out – 作为该运算符的输出而生成的解的数量。DFEDrain 是一种特殊情况,其中被排除的解的数量记录在 Units In 中,并且 Units Out 始终为零。
Ratio – Units Out 与 Units In 的比率。
Time (ms) – 此运算符消耗的 CPU 时间,以毫秒为单位。
openCypher explain 输出的一个基本示例
以下是 openCypher explain 输出的基本示例。该查询是在航线数据集中针对机场代码为 ATL 的节点执行的单节点查找,它使用默认 ASCII 输出格式的 details 模式调用 explain:
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 出现在其它所有内容之前,其 Units Out 为 1。请注意,它实际上并没有注入任何解。您可以看到下一个运算符 DFESubquery 的 Units In 为 0。
在顶层的 SolutionInjection 之后是 DFESubquery 和 TermResolution 运算符。DFESubquery 封装查询执行计划中正在推送到 DFE 引擎的部分(对于 openCypher 查询,整个查询计划由 DFE 执行)。查询计划中的所有运算符都嵌套在由 DFESubquery 引用的 subQuery1 内部。唯一的例外是TermResolution,它在内部实现 IDs 为完全序列化的 OpenCypher 对象。
所有下推到 DFE 引擎的运算符的名称都以 DFE 前缀开头。如上所述,整个 openCypher 查询计划由 DFE 执行,因此,除最后一个 TermResolution 运算符之外的所有运算符都以 DFE 开头。
在 subQuery1 内部,可以有零个或多个 DFEChunkLocalSubQuery 或 DFELoopSubQuery 运算符来封装在内存受限机制中执行的推送执行计划的一部分。这里的 DFEChunkLocalSubQuery 包含一个 SolutionInjection,它用作子查询的输入。要在输出中查找该子查询的表,请在 Arguments 列中搜索为 DFEChunkLocalSubQuery 或 DFELoopSubQuery 运算符指定的 subQuery=。graph URI
在 subQuery1 中,ID 为 0 的 DFEPipelineScan 扫描数据库以查找指定的 pattern。该模式在所有标签上扫描属性 code 保存为变量 ?n_code2 的实体(可以通过将 airport 附加到 n:airport 来针对特定标签进行筛选)。inlineFilters 参数显示了针对等于 ATL 的 code 属性的筛选。
接下来,DFEChunkLocalSubQuery 运算符联接包含 DFEPipelineJoin 的子查询的中间结果。这可以确保 ?n 实际上是一个节点,因为之前的 DFEPipelineScan 会扫描任何具有 code 属性的实体。