View a markdown version of this page

Verwendung der Gremlin Explain API in Neptune - Amazon Neptune

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Verwendung der Gremlin Explain API in Neptune

Die Amazon-Neptune-Gremlin-explain-API gibt den Abfrageplan zurück, der ausgeführt würde, wenn eine bestimmte Abfrage ausgeführt würde. Da die API die Abfrage nicht tatsächlich ausführt, wird der Plan fast sofort zurückgegeben.

Er unterscheidet sich vom Schritt TinkerPop .explain (), um spezifische Informationen für die Neptune-Engine melden zu können.

Informationen, die in einem Gremlin Explain-Bericht enthalten sind

Der explain-Bericht enthält die folgenden Informationen:

  • Die Abfragezeichenfolge, wie gewünscht.

  • Die ursprüngliche Traversierung. Dies ist das TinkerPop Traversal-Objekt, das durch das Parsen der Abfragezeichenfolge in Schritten erzeugt wird. TinkerPop Es entspricht der ursprünglichen Abfrage, die erstellt wurde, indem die Abfrage gegen die .explain() ausgeführt wurde. TinkerPop TinkerGraph

  • Die konvertierte Traversierung. Dies ist der Neptun-Traversal, der durch die Konvertierung der TinkerPop Traversal in die logische Neptun-Abfrageplandarstellung erzeugt wird. In vielen Fällen wird die gesamte TinkerPop Durchquerung in zwei Neptun-Schritte umgewandelt: einen, der die gesamte Abfrage ausführt (NeptuneGraphQueryStep) und einen, der die Ausgabe der Neptune-Abfrage-Engine wieder in Traversers () umwandelt. TinkerPop NeptuneTraverserConverterStep

  • Die optimierte Traversierung. Dies ist die optimierte Version des Neptune-Abfrageplans, nachdem dieser von mehreren statischen, den Aufwand reduzierenden Optimierern verarbeitet wurde, die die Abfrage basierend auf statischen Analysen und geschätzten Kardinalitäten neu schreiben. Diese Optimierer erledigen Aufgaben wie die Neuanordnung von Operatoren basierend auf der Bereichsanzahl, das Reduzieren unnötiger oder redundanter Operatoren, das Neuanordnen von Filtern, das Verschieben von Operatoren in verschiedene Gruppen und so weiter.

  • Die Anzahl der Prädikate. Aufgrund der zuvor beschriebenen Neptune-Indizierungsstrategie können zahlreiche unterschiedliche Prädikate zu Leistungsproblemen führen. Dies gilt insbesondere für Abfragen, die Reverse-Transversal-Operatoren ohne Grenzbezeichnung (.in oder .both) verwenden. Wenn solche Operatoren verwendet werden und die Anzahl der Prädikate hoch genug ist, zeigt der explain-Bericht eine Warnmeldung an.

  • DFE-Informationen. Wenn die alternative DFE-Engine aktiviert ist, können die folgenden Traversierungskomponenten in der optimierten Traversierung erscheinen:

    • DFEStep   –   Ein Neptune-optimierter DFE-Schritt in der Traversierung mit einem untergeordneten DFENode. DFEStep stellt den Teil des Abfrageplans dar, der in der DFE-Engine ausgeführt wird.

    • DFENode   –   Enthält die Zwischendarstellung als einen oder mehrere untergeordnete DFEJoinGroupNodes.

    • DFEJoinGroupNode   –   Stellt eine Verbindung von einem oder mehreren DFENode- oder DFEJoinGroupNode-Elementen dar.

    • NeptuneInterleavingStep   –   Ein Neptune-optimierter DFE-Schritt in der Traversierung mit einem untergeordneten DFEStep.

      Enthält außerdem ein stepInfo-Element mit Informationen zur Traversierung, z. B. das Grenzelement, die verwendeten Pfadelemente usw. Diese Informationen werden zur Verarbeitung des untergeordneten DFEStep verwendet.

    Eine einfache Art, festzustellen, ob Ihre Abfrage von DFE ausgewertet wird, besteht in der Überprüfung, ob die explain-Ausgabe einen DFEStep enthält. Jeder Teil der Durchquerung, der nicht Teil von ist, wird nicht von DFE ausgeführt, sondern von der DFEStep Engine ausgeführt. TinkerPop

    Einen Beispielbericht finden Sie unter Beispiel mit DFE-Aktivierung.

Gremlin erklärt die Syntax

Die Syntax der explain API ist dieselbe wie die der HTTP-API für Abfragen, außer dass sie anstelle von /gremlin/explain als Endpunkt verwendet wird/gremlin, wie in den folgenden Beispielen.

AWS CLI
aws neptunedata execute-gremlin-explain-query \ --endpoint-url https://your-neptune-endpoint:port \ --gremlin-query "g.V().limit(1)"

Weitere Informationen finden Sie unter execute-gremlin-explain-query in der Befehlsreferenz. AWS CLI

SDK
import boto3 from botocore.config import Config client = boto3.client( 'neptunedata', endpoint_url='https://your-neptune-endpoint:port', config=Config(read_timeout=None, retries={'total_max_attempts': 1}) ) response = client.execute_gremlin_explain_query( gremlinQuery='g.V().limit(1)' ) print(response['output'])

AWS SDK-Beispiele in anderen Sprachen wie Java, .NET und mehr finden Sie unter. AWS SDK

awscurl
awscurl https://your-neptune-endpoint:port/gremlin/explain \ --region us-east-1 \ --service neptune-db \ -X POST \ -d '{"gremlin":"g.V().limit(1)"}'
Anmerkung

In diesem Beispiel wird davon ausgegangen, dass Ihre AWS Anmeldeinformationen in Ihrer Umgebung konfiguriert sind. Ersetze es us-east-1 durch die Region deines Neptun-Clusters.

Weitere Informationen zur Verwendung awscurl mit der IAM-Authentifizierung finden Sie unter. Verwenden von awscurl mit temporären Anmeldeinformationen, um eine sichere Verbindung zu einem DB-Cluster mit aktivierter IAM-Authentifizierung herzustellen

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

Die vorherige Abfrage würde die folgende Ausgabe erzeugen.

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

Nicht konvertierte Schritte TinkerPop

Im Idealfall werden alle TinkerPop Schritte einer Traversierung von einem eigenen Neptun-Operator abgedeckt. Wenn dies nicht der Fall ist, greift Neptune aufgrund von Lücken in der TinkerPop Bedienerabdeckung auf die Step-Ausführung zurück. Wenn eine Traversierung einen Schritt verwendet, für den Neptune noch keine native Abdeckung besitzt, zeigt der explain-Bericht eine Warnung an, die angibt, wo die Lücke aufgetreten ist.

Wenn ein Schritt ohne einen entsprechenden nativen Neptun-Operator angetroffen wird, wird die gesamte Traversierung von diesem Punkt an mithilfe von Schritten ausgeführt, auch wenn nachfolgende TinkerPop Schritte native Neptun-Operatoren haben.

Eine Ausnahme bilden Aufrufe von Neptune-Volltextsuchen. Der NeptuneSearchStep implementiert Schritte ohne systemeigene Entsprechungen als Volltextsuchschritte.

Beispiel für eine Explain-Ausgabe, bei der alle Schritte in einer Abfrage systemeigene Entsprechungen haben

Dies ist ein Beispielbericht für explain für eine Abfrage, in der es für alle Schritte native Entsprechungen gibt.

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

Beispiel, in dem es für einige Abfrageschritte keine nativen Entsprechungen gibt

Neptune verarbeitet GraphStep und VertexStep nativ. Wenn Sie jedoch FoldStep und UnfoldStep einführen, unterscheidet sich die explain-Ausgabe:

******************************************************* 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 diesem Fall hebt FoldStep die native Ausführung auf. Aber auch die nachfolgende VertexStep wird nicht mehr nativ behandelt, da sie den Fold/Unfold-Schritten nachgelagert erscheint.

Um Leistung und Kosteneinsparungen zu erzielen, ist es wichtig, dass Sie versuchen, Traversals so zu formulieren, dass der größtmögliche Arbeitsaufwand nativ in der Neptune-Abfrage-Engine erledigt wird, anstatt schrittweise Implementierungen vorzunehmen. TinkerPop

Beispiel für eine Abfrage mit Verwendung der Neptune-Volltextsuche

Die folgende Abfrage verwendet die Neptune-Volltextsuche:

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

Der Teil .has("name", "Neptune#fts mark*") beschränkt die Suche auf Eckpunkte mit name, während .has("Person", "name", "Neptune#fts mark*") die Suche auf Eckpunkte mit name und der Beschriftung Person beschränkt. Dies führt zur folgenden Traversierung im explain-Bericht:

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} } }]

Beispiel für die Verwendung von Explain bei aktiviertem DFE

Dies ist ein Beispiel für einen explain-Bericht bei Aktivierung der alternativen DFE-Abfrage-Engine:

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

Eine Beschreibung der DFE-specific Abschnitte im Bericht finden Informationen in explain Sie unter.