Usare il Gremlin explain API in Neptune - Amazon Neptune

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Usare il Gremlin explain API in Neptune

Amazon Neptune explain API Gremlin restituisce il piano di query che verrebbe eseguito se venisse eseguita una query specificata. Poiché in realtà API non esegue la query, il piano viene restituito quasi istantaneamente.

Si differenzia dal passaggio TinkerPop .explain () per poter riportare informazioni specifiche per il motore Neptune.

Informazioni contenute in un report Gremlin explain

Il report explain contiene le seguenti informazioni:

  • La stringa di query che è stata richiesta.

  • L'attraversamento originale. Questo è l'oggetto TinkerPop Traversal prodotto analizzando la stringa di query in passaggi. TinkerPop È equivalente alla query originale prodotta eseguendo la query .explain() su. TinkerPop TinkerGraph

  • L'attraversamento convertito. Questo è il Neptune Traversal prodotto convertendo il Traversal nella rappresentazione del piano di interrogazione TinkerPop logica di Neptune. In molti casi l'intero TinkerPop attraversamento viene convertito in due passaggi di Neptune: uno che esegue l'intera query () NeptuneGraphQueryStep e uno che converte l'output del motore di query Neptune in Traversers (). TinkerPop NeptuneTraverserConverterStep

  • L'attraversamento ottimizzato. Questa è la versione ottimizzata del piano di query Neptune dopo che è stato eseguito tramite una serie di ottimizzatori di riduzione del lavoro statici che riscrivono la query in base all'analisi statica e alle cardinalità stimate. Questi ottimizzatori eseguono operazioni come riordinare operatori in base a conteggi di intervalli, eliminare operatori superflui o ridondanti, riordinare i filtri, eseguire il push di operatori in gruppi diversi e così via.

  • Il conteggio di predicati. A causa della strategia di indicizzazione Neptune descritta in precedenza, avere un numero elevato di predicati diversi può causare problemi di prestazioni. Ciò vale soprattutto per query che utilizzano operatori di attraversamento inverso senza etichetta edge (.in o .both). Se vengono utilizzati tali operatori e il conteggio di predicati è sufficientemente elevato, il report explain visualizza un messaggio di avviso.

  • DFEinformazioni. Quando il motore DFE alternativo è abilitato, nell'attraversamento ottimizzato possono apparire i seguenti componenti di attraversamento:

    • DFEStep— Una fase dell'attraversamento DFE ottimizzata per Neptune che contiene un bambino. DFENode DFESteprappresenta la parte del piano di interrogazione che viene eseguita nel motore. DFE

    • DFENode: contiene la rappresentazione intermedia come uno o più oggetti DFEJoinGroupNodes figlio.

    • DFEJoinGroupNode: rappresenta l'unione di uno o più elementi DFENode o DFEJoinGroupNode.

    • NeptuneInterleavingStep— Una fase dell'attraversamento DFE ottimizzata per Neptune che contiene un bambino. DFEStep

      Contiene anche un elemento stepInfo che contiene informazioni sull'attraversamento, come l'elemento di frontiera, gli elementi di percorso utilizzati e così via. Queste informazioni vengono utilizzate per elaborare l'oggetto DFEStep figlio.

    Un modo semplice per scoprire se la query viene valutata da DFE è verificare se l'output contiene un. explain DFEStep Qualsiasi parte dell'attraversamento che non fa parte di non DFEStep verrà eseguita DFE e verrà eseguita dal motore. TinkerPop

    Vedi Esempio con DFE abilitato per un report di esempio.

Sintassi di Gremlin explain

La sintassi di explain API è la stessa della query for, tranne HTTP API per il fatto che viene utilizzata /gremlin/explain come endpoint anziché/gremlin, come nell'esempio seguente.

curl -X POST https://your-neptune-endpoint:port/gremlin/explain -d '{"gremlin":"g.V().limit(1)"}'

La query precedente produrrebbe il seguente output.

******************************************************* 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

Passaggi non convertiti TinkerPop

Idealmente, tutte le TinkerPop fasi di un attraversamento hanno una copertura dell'operatore Neptune nativa. In caso contrario, Neptune ricorre all'esecuzione a fasi per eventuali lacune TinkerPop nella copertura degli operatori. Se un attraversamento utilizza un passaggio per il quale Neptune non dispone ancora di copertura nativa, il report explain visualizza un avviso che mostra dove si è verificata la lacuna.

Quando viene rilevato un passaggio senza un corrispondente operatore Neptune nativo, l'intero attraversamento da quel punto in poi viene eseguito TinkerPop utilizzando i passaggi, anche se i passaggi successivi hanno operatori Neptune nativi.

L'eccezione a questo è quando viene richiamata la ricerca full-text Neptune. NeptuneSearchStep Implementa passaggi senza equivalenti nativi come passaggi di ricerca a testo completo.

Esempio di output di explain in cui tutti i passaggi di una query dispongono di equivalenti nativi

Di seguito è riportato un esempio di report di explain per una query in cui tutti i passaggi dispongono di equivalenti nativi:

******************************************************* 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

Esempio in cui alcune fasi in una query non dispongono di equivalenti nativi

Neptune gestisce GraphStep e VertexStep in modo nativo, ma se si introduce FoldStep e UnfoldStep, l'output risultante di explain è diverso:

******************************************************* 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

In questo caso, FoldStep interrompe l'esecuzione nativa. Tuttavia, anche la VertexStep successiva non viene più gestita in modo nativo perché viene visualizzato a valle delle fasi Fold/Unfold.

Per migliorare le prestazioni e ridurre i costi, è importante provare a formulare trasversali in modo che la massima quantità di lavoro possibile venga eseguita nativamente all'interno del motore di query Neptune, anziché implementazioni graduali. TinkerPop

Esempio di una query che utilizza Neptune full-text-search

La query seguente utilizza la ricerca full-text 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 ricerca ai vertici con name, mentre .has("Person", "name", "Neptune#fts mark*") limita la ricerca ai vertici con name e all'etichetta Person. Ciò ha come risultato il seguente attraversamento nel report di 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} } }]

Esempio di utilizzo explain quando è abilitato DFE

Di seguito è riportato un esempio di explain report quando il motore di query DFE alternativo è abilitato:

******************************************************* 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

Informazioni in explainPer una descrizione delle sezioni DFE specifiche del rapporto, vedere.