Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
La API de explain
de Gremlin de Amazon Neptune devuelve el plan de consulta que se ejecutaría si se realizara una consulta especificada. Puesto que la API no ejecuta realmente la consulta, el plan se devuelve casi instantáneamente.
Se diferencia del paso TinkerPop .explain () para poder reportar información específica del motor de Neptune.
Información contenida en un informe explain
de Gremlin
Un informe explain
contiene la siguiente información:
La cadena de consulta según se solicita.
El recorrido original. Este es el objeto TinkerPop Traversal que se produce al analizar la cadena de consulta en pasos. TinkerPop Es equivalente a la consulta original producida al ejecutar
.explain()
la consulta contra el. TinkerPop TinkerGraphEl recorrido convertido. Este es el recorrido de Neptuno producido al convertir el TinkerPop recorrido en la representación del plan de consulta lógico de Neptuno. En muchos casos, todo el TinkerPop recorrido se convierte en dos pasos de Neptuno: uno que ejecuta toda la consulta
NeptuneGraphQueryStep
() y otro que convierte la salida del motor de consultas de Neptuno en Traversers (). TinkerPopNeptuneTraverserConverterStep
El recorrido optimizado. Esta es la versión optimizada del plan de consultas de Neptune después de que se haya ejecutado a través de una serie de optimizadores estáticos de reducción de trabajo que reescriben la consulta en función del análisis estático y las cardinalidades estimadas. Esos optimizadores realizan tareas como reordenar operadores en función del recuento de rangos, eliminar operadores innecesarios o redundantes, reorganizar filtros, insertar operadores en diferentes grupos, etc.
El recuento de predicados. Debido a la estrategia de indexación de Neptune descrita anteriormente, disponer de un gran número de predicados diferentes puede provocar problemas de rendimiento. Esto es especialmente cierto para las consultas que utilizan operadores de recorrido inverso sin etiqueta de borde (
.in
o.both
). Si se utilizan estos operadores y el recuento de predicados es lo suficientemente alto, el informeexplain
muestra un mensaje de advertencia.-
Información de DFE Cuando el motor alternativo de DFE está habilitado, es posible que los siguientes componentes de recorrido aparezcan en el recorrido optimizado:
-
DFEStep
: un paso de DFE optimizado para Neptune en el recorrido que contiene unDFENode
secundario.DFEStep
representa la parte del plan de consultas que se ejecuta en el motor DFE. -
DFENode
: contiene la representación intermedia como uno o másDFEJoinGroupNodes
secundarios. -
DFEJoinGroupNode
: representa una unión de uno o más elementosDFENode
oDFEJoinGroupNode
. -
NeptuneInterleavingStep
: un paso de DFE optimizado para Neptune en el recorrido que contiene unDFEStep
secundario.También contiene un elemento
stepInfo
que contiene información sobre el recorrido, como el elemento fronterizo, los elementos de la ruta utilizados, etc. Esta información se usa para procesar elDFEStep
secundario.
Una forma sencilla de averiguar si el DFE está evaluando su consulta consiste en comprobar si el resultado de
explain
contiene unDFEStep
. Cualquier parte del recorrido que no forme parte del recorrido no será ejecutada por el DFE yDFEStep
será ejecutada por el motor. TinkerPopConsulte Ejemplo con DFE habilitado para ver un informe de ejemplo.
-
Sintaxis de explain
de Gremlin
La sintaxis de la API explain
es la misma que la de la API HTTP para consultas, salvo que utiliza /gremlin/explain
como punto de enlace en lugar de /gremlin
, como en el siguiente ejemplo.
curl -X POST https://
your-neptune-endpoint
:port
/gremlin/explain -d '{"gremlin":"g.V().limit(1)"}'
La consulta anterior produciría el siguiente resultado.
******************************************************* Neptune Gremlin Explain ******************************************************* Query String ============ g.V().limit(1) Original Traversal ================== [GraphStep(vertex,[]), RangeGlobalStep(0,1)] Converted Traversal =================== Neptune steps: [ NeptuneGraphQueryStep(Vertex) { JoinGroupNode { PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .] }, finishers=[limit(1)], annotations={path=[Vertex(?1):GraphStep], maxVarId=3} }, NeptuneTraverserConverterStep ] Optimized Traversal =================== Neptune steps: [ NeptuneGraphQueryStep(Vertex) { JoinGroupNode { PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .], {estimatedCardinality=INFINITY} }, finishers=[limit(1)], annotations={path=[Vertex(?1):GraphStep], maxVarId=3} }, NeptuneTraverserConverterStep ] Predicates ========== # of predicates: 18
Pasos no convertidos TinkerPop
Lo ideal es que todos los TinkerPop pasos de un recorrido cuenten con la cobertura nativa del operador de Neptune. Cuando este no es el caso, Neptune recurre a la ejecución TinkerPop escalonada para cubrir las brechas en la cobertura de sus operadores. Si un recorrido utiliza un paso para el que Neptune todavía no tiene cobertura nativa, el informe explain
muestra una advertencia que indica dónde se produjo la brecha.
Cuando se encuentra un paso sin un operador nativo de Neptuno correspondiente, todo el recorrido desde ese punto en adelante se ejecuta mediante TinkerPop pasos, incluso si los pasos posteriores tienen operadores nativos de Neptuno.
La excepción a esto se produce cuando se invoca la búsqueda de texto completo de Neptune. NeptuneSearchStep Implementa los pasos sin equivalentes nativos como pasos de búsqueda de texto completo.
Ejemplo de resultado de explain
donde todos los pasos de una consulta tienen equivalentes nativos
A continuación se muestra un ejemplo de informe explain
para una consulta en la que todos los pasos tienen equivalentes nativos:
******************************************************* Neptune Gremlin Explain ******************************************************* Query String ============ g.V().out() Original Traversal ================== [GraphStep(vertex,[]), VertexStep(OUT,vertex)] Converted Traversal =================== Neptune steps: [ NeptuneGraphQueryStep(Vertex) { JoinGroupNode { PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .] PatternNode[(?1, ?5, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .] PatternNode[(?3, <~label>, ?4, <~>) . project ask .] }, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep], maxVarId=7} }, NeptuneTraverserConverterStep ] Optimized Traversal =================== Neptune steps: [ NeptuneGraphQueryStep(Vertex) { JoinGroupNode { PatternNode[(?1, ?5, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .], {estimatedCardinality=INFINITY} }, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep], maxVarId=7} }, NeptuneTraverserConverterStep ] Predicates ========== # of predicates: 18
Ejemplo en el que algunos pasos de una consulta no tienen equivalentes nativos
Neptune gestiona GraphStep
y VertexStep
de forma nativa, pero si introduce un FoldStep
y UnfoldStep
, el explain
resultante es diferente.
******************************************************* Neptune Gremlin Explain ******************************************************* Query String ============ g.V().fold().unfold().out() Original Traversal ================== [GraphStep(vertex,[]), FoldStep, UnfoldStep, VertexStep(OUT,vertex)] Converted Traversal =================== Neptune steps: [ NeptuneGraphQueryStep(Vertex) { JoinGroupNode { PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .] }, annotations={path=[Vertex(?1):GraphStep], maxVarId=3} }, NeptuneTraverserConverterStep ] + not converted into Neptune steps: [FoldStep, UnfoldStep, VertexStep(OUT,vertex)] Optimized Traversal =================== Neptune steps: [ NeptuneGraphQueryStep(Vertex) { JoinGroupNode { PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .], {estimatedCardinality=INFINITY} }, annotations={path=[Vertex(?1):GraphStep], maxVarId=3} }, NeptuneTraverserConverterStep, NeptuneMemoryTrackerStep ] + not converted into Neptune steps: [FoldStep, UnfoldStep, VertexStep(OUT,vertex)] WARNING: >> FoldStep << is not supported natively yet
En este caso, FoldStep
elimina la ejecución nativa. Sin embargo, incluso el VertexStep
siguiente ya no se gestiona de forma nativa, ya que aparece después de los pasos Fold/Unfold
.
Para ahorrar rendimiento y costes, es importante que intente formular los recorridos de forma que la mayor cantidad de trabajo posible se realice de forma nativa dentro del motor de consultas de Neptune, en lugar de hacerlo paso a paso. TinkerPop
Ejemplo de consulta que usa Neptune full-text-search
En la siguiente consulta se utiliza la búsqueda de texto completo de Neptune:
g.withSideEffect("
Neptune#fts.endpoint
", "some_endpoint
") .V() .tail(100) .has("Neptune#fts mark*") ------- .has("name", "Neptune#fts mark*") .has("Person", "name", "Neptune#fts mark*")
La parte .has("name", "Neptune#fts mark*")
limita la búsqueda a los vértices con name
, mientras que .has("Person", "name", "Neptune#fts mark*")
limita la búsqueda a los vértices con name
y la etiqueta Person
. Esto da como resultado el siguiente recorrido en el informe explain
:
Final Traversal [NeptuneGraphQueryStep(Vertex) { JoinGroupNode { PatternNode[(?1, termid(1,URI), ?2, termid(0,URI)) . project distinct ?1 .], {estimatedCardinality=INFINITY} }, annotations={path=[Vertex(?1):GraphStep], maxVarId=4} }, NeptuneTraverserConverterStep, NeptuneTailGlobalStep(10), NeptuneTinkerpopTraverserConverterStep, NeptuneSearchStep { JoinGroupNode { SearchNode[(idVar=?3, query=mark*, field=name) . project ask .], {endpoint=some_endpoint} } JoinGroupNode { SearchNode[(idVar=?3, query=mark*, field=name) . project ask .], {endpoint=some_endpoint} } }]
Ejemplo de uso de explain
cuando DFE está habilitado
El siguiente es un ejemplo de un informe explain
cuando el motor de consultas alternativo DFE está habilitado:
******************************************************* Neptune Gremlin Explain ******************************************************* Query String ============ g.V().as("a").out().has("name", "josh").out().in().where(eq("a")) Original Traversal ================== [GraphStep(vertex,[])@[a], VertexStep(OUT,vertex), HasStep([name.eq(josh)]), VertexStep(OUT,vertex), VertexStep(IN,vertex), WherePredicateStep(eq(a))] Converted Traversal =================== Neptune steps: [ DFEStep(Vertex) { DFENode { DFEJoinGroupNode[ children={ DFEPatternNode[(?1, <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, ?2, <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph>) . project DISTINCT[?1] {rangeCountEstimate=unknown}], DFEPatternNode[(?1, ?3, ?4, ?5) . project ALL[?1, ?4] graphFilters=(!= <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph> . ), {rangeCountEstimate=unknown}] }, {rangeCountEstimate=unknown} ] } [Vertex(?1):GraphStep@[a], Vertex(?4):VertexStep] } , NeptuneTraverserConverterDFEStep ] + not converted into Neptune steps: HasStep([name.eq(josh)]), Neptune steps: [ NeptuneInterleavingStep { StepInfo[joinVars=[?7, ?1], frontierElement=Vertex(?7):HasStep, pathElements={a=(last,Vertex(?1):GraphStep@[a])}, listPathElement={}, indexTime=0ms], DFEStep(Vertex) { DFENode { DFEJoinGroupNode[ children={ DFEPatternNode[(?7, ?8, ?9, ?10) . project ALL[?7, ?9] graphFilters=(!= <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph> . ), {rangeCountEstimate=unknown}], DFEPatternNode[(?12, ?11, ?9, ?13) . project ALL[?9, ?12] graphFilters=(!= <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph> . ), {rangeCountEstimate=unknown}] }, {rangeCountEstimate=unknown} ] } [Vertex(?9):VertexStep, Vertex(?12):VertexStep] } } ] + not converted into Neptune steps: WherePredicateStep(eq(a)), Neptune steps: [ DFECleanupStep ] Optimized Traversal =================== Neptune steps: [ DFEStep(Vertex) { DFENode { DFEJoinGroupNode[ children={ DFEPatternNode[(?1, ?3, ?4, ?5) . project ALL[?1, ?4] graphFilters=(!= defaultGraph[526] . ), {rangeCountEstimate=9223372036854775807}] }, {rangeCountEstimate=unknown} ] } [Vertex(?1):GraphStep@[a], Vertex(?4):VertexStep] } , NeptuneTraverserConverterDFEStep ] + not converted into Neptune steps: NeptuneHasStep([name.eq(josh)]), Neptune steps: [ NeptuneMemoryTrackerStep, NeptuneInterleavingStep { StepInfo[joinVars=[?7, ?1], frontierElement=Vertex(?7):HasStep, pathElements={a=(last,Vertex(?1):GraphStep@[a])}, listPathElement={}, indexTime=0ms], DFEStep(Vertex) { DFENode { DFEJoinGroupNode[ children={ DFEPatternNode[(?7, ?8, ?9, ?10) . project ALL[?7, ?9] graphFilters=(!= defaultGraph[526] . ), {rangeCountEstimate=9223372036854775807}], DFEPatternNode[(?12, ?11, ?9, ?13) . project ALL[?9, ?12] graphFilters=(!= defaultGraph[526] . ), {rangeCountEstimate=9223372036854775807}] }, {rangeCountEstimate=unknown} ] } [Vertex(?9):VertexStep, Vertex(?12):VertexStep] } } ] + not converted into Neptune steps: WherePredicateStep(eq(a)), Neptune steps: [ DFECleanupStep ] WARNING: >> [NeptuneHasStep([name.eq(josh)]), WherePredicateStep(eq(a))] << (or one of the children for each step) is not supported natively yet Predicates ========== # of predicates: 8
Consulte Información en explain para obtener una descripción de las secciones específicas de DFE en el informe.