OpencyPherexplain 功能 - Amazon Neptune
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

OpencyPherexplain 功能

OpencyPherexplain 功能是 Amazon Neptune 中的一个自助工具,可帮助您了解Neptune 引擎采用的执行方法。要调用 explain,您可以使用explain=mode向 OpencyPher HTTPS 请求传递一个参数,其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 的当前版本存在以下限制:

  • 解释计划目前仅适用于执行只读操作的查询。不支持执行任何类型突变的查询CREATEDELETEMERGESET,例如、、等。

  • 在future 版本中,特定计划的运算符和输出可能会发生变化。

OpencyPherexplain 输出中的 DFE 运算符

要使用 OpencyPherexplain 功能提供的信息,你需要了解有关 DFE 查询引擎工作原理的一些细节(DF E 是 Neptune 用来处理 OpencyPher 查询的引擎)。

DFE 引擎将每个查询转换为运算符管道。从第一个操作员开始,中间解决方案通过该操作流水线从一个操作员流向下一个操作员。解释表中的每一行都代表一个结果,直到评估为止。

可以出现在 DFE 查询计划中的运算符如下:

dfeApply — 对存储functor在指定变量中的值执行参数部分中指定的函数

DFEBindRelation — 将具有指定名称的变量绑定在一起

DFEChunkLocalSubQuery — 这是一种非阻塞操作,用作正在执行的子查询的封装。

DFEDistinctColumn — 根据指定的变量返回输入值的不同子集。

DFEDistinctRelation — 根据指定的变量返回输入解的不同子集。

dfeDra in — 出现在子查询的末尾,用作该子查询的终止步骤。解决方案的数量记录为Units InUnits Out始终为零。

DFELoopSubQuery — 这是一种非阻塞操作,用作子查询的封装,允许其重复运行以在循环中使用。

DFEOptionalJoin — 执行可选联接A OPTIONAL B ≡ (A JOIN B) UNION (A MINUS_NE B)。这是一个阻止性操作。

DFEPipelineJoin — 根据pattern参数定义的元组模式连接输入。

DFEPipelineScan-扫描数据库中的给定pattern参数,无论是否对列使用给定过滤器。

DFEProjec t-接受多个输入列,仅投影所需的列。

dfeRedu ce — 对指定变量执行指定的聚合函数。

DFERelationalJoin — 使用合并联接根据指定的模式键加入前一个运算符的输入。这是一个阻止性操作。

DFERelationalJoin — 使用合并联接根据指定的模式键加入前一个运算符的输入。这是一个阻止性操作。

dfeSubQuery — 此运算符出现在所有计划的开头,概括了计划中在 DFE 引擎上运行的部分,即 OpencyPher 的整个计划。

DFESymmetricHashJoin — 使用哈希联接根据指定的模式键加入前一个运算符的输入。这是一项非阻塞操作。

DFetee — 这是一个分支运算符,它向多个运算符发送相同的解集。

SolutionInjection— 出现在explain输出中所有其他内容之前,Units Out列中的值为 1。但是,它不起作用,实际上并没有向 DFE 引擎注入任何解决方案。

TermResolution— 出现在计划末尾,并将来自Neptune 引擎的物体转换为 OpencyPher 物体。

OpencyPherexplain 输出中的列

Neptune 在 OpencyPher 解释输出时生成的查询计划信息包含每行一个运算符的表。表具有以下几列:

ID — 计划中此操作员的数字 ID。

Ou t #1(和 Ou t #2)— 该运算符下游的运算符的 ID。最多可以有两个下游运算符。

名称-此操作员的姓名。

参数 — 操作员的任何相关细节。这包括输入架构、输出架构、模式(用于PipelineScanPipelineJoin)等内容。

模式-描述基本操作员行为的标签。此列大部分为空 (-)。一个例外是TermResolution,模式可以是id2value_opencypher,表示从 ID 到 OpencyPher 值的分辨率。

输入单位-作为输入传递给该运算符的解的数量。没有上游运算符的运算符DFEPipelineScan,例如SolutionInjections、和没有注入静态值的 aDFESubquery,其值将为零。

Units Out — 此运算符输出时产生的解决方案数量。 DFEDrain是一种特殊情况,其中记录了正在耗尽的解的数量,Units In并且始终Units Out为零。

比率 — 与Units Out的比率Units In

时间 (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层之后是DFESubqueryTermResolution运算符。 DFESubquery封装了推送到 DFE 引擎的查询执行计划部分(对于 OpencyPher 查询,整个查询计划由 DFE 执行)。查询计划中的所有运算符都嵌套在subQuery1所引用的内部DFESubquery。唯一的例外是TermResolution,它将内部 ID 具体化为完全序列化的 OpencyPher 对象。

所有推送到 DFE 引擎的运算符的名称都以DFE前缀开头。如上所述,整个 OpencyPher 查询计划由 DFE 执行,因此,除最终运算符外,所有TermResolution运算符均以开头DFE

在内部subQuery1,可以有零个DFEChunkLocalSubQuery或多个或DFELoopSubQuery运算符封装在内存限制机制中执行的推送执行计划的一部分。 DFEChunkLocalSubQuery这里SolutionInjection包含一个用作子查询输入的内容。要在输出中查找该子查询的表,请在Arguments列中搜索subQuery=graph URI指定的 oDFEChunkLocalSubQuery rDFELoopSubQuery 运算符。

在中subQuery1DFEPipelineScan,使用ID 0 扫描数据库中的指定值pattern。该模式会扫描一个实体,该实体code将属性另存为所有标签的变量(您可以通过附加airport到对特定标签进行?n_code2过滤n:airport)。该inlineFilters参数显示了对等于属code性的过滤ATL

接下来,DFEChunkLocalSubQuery运算符连接包含的子查询的中间结果DFEPipelineJoin。这样可以确保?n它实际上是一个节点,因为之前的版本DFEPipelineScan会扫描任何具有该code属性的实体。