Sdílet prostřednictvím


Vyhodnocování dotazů Gremlin s využitím kroku profilu spuštění

PLATÍ PRO: Skřítek

Tento článek obsahuje přehled použití kroku profilu spouštění pro grafové databáze Azure Cosmos DB pro grafové databáze Gremlin. Tento krok poskytuje relevantní informace pro účely řešení potíží a optimalizace dotazů a je kompatibilní se všemi dotazy Gremlin, které je možné spustit pro účet rozhraní Gremlin API služby Cosmos DB.

Pokud chcete tento krok použít, jednoduše připojte executionProfile() volání funkce na konec dotazu Gremlin. Váš dotaz Gremlin se spustí a výsledek operace vrátí objekt odpovědi JSON s profilem spuštění dotazu.

Příklad:

    // Basic traversal
    g.V('mary').out()

    // Basic traversal with execution profile call
    g.V('mary').out().executionProfile()

Po zavolání executionProfile() kroku bude odpovědí objekt JSON, který zahrnuje spuštěný krok Gremlin, celkovou dobu, kterou trvalo, a pole operátorů modulu runtime Cosmos DB, které příkaz způsobil.

Poznámka:

Tato implementace profilu spuštění není definována ve specifikaci Apache Tinkerpop. Je specifická pro implementaci Služby Gremlin ve službě Azure Cosmos DB.

Příklad odpovědi

Následuje příklad výstupu s poznámkami, který se vrátí:

Poznámka:

Tento příklad je opatřen poznámkami, které vysvětlují obecnou strukturu odpovědi. Skutečná odpověď executionProfile nebude obsahovat žádné komentáře.

[
  {
    // The Gremlin statement that was executed.
    "gremlin": "g.V('mary').out().executionProfile()",

    // Amount of time in milliseconds that the entire operation took.
    "totalTime": 28,

    // An array containing metrics for each of the steps that were executed. 
    // Each Gremlin step will translate to one or more of these steps.
    // This list is sorted in order of execution.
    "metrics": [
      {
        // This operation obtains a set of Vertex objects.
        // The metrics include: time, percentTime of total execution time, resultCount, 
        // fanoutFactor, count, size (in bytes) and time.
        "name": "GetVertices",
        "time": 24,
        "annotations": {
          "percentTime": 85.71
        },
        "counts": {
          "resultCount": 2
        },
        "storeOps": [
          {
            "fanoutFactor": 1,
            "count": 2,
            "size": 696,
            "time": 0.4
          }
        ]
      },
      {
        // This operation obtains a set of Edge objects. 
        // Depending on the query, these might be directly adjacent to a set of vertices, 
        // or separate, in the case of an E() query.
        //
        // The metrics include: time, percentTime of total execution time, resultCount, 
        // fanoutFactor, count, size (in bytes) and time.
        "name": "GetEdges",
        "time": 4,
        "annotations": {
          "percentTime": 14.29
        },
        "counts": {
          "resultCount": 1
        },
        "storeOps": [
          {
            "fanoutFactor": 1,
            "count": 1,
            "size": 419,
            "time": 0.67
          }
        ]
      },
      {
        // This operation obtains the vertices that a set of edges point at.
        // The metrics include: time, percentTime of total execution time and resultCount.
        "name": "GetNeighborVertices",
        "time": 0,
        "annotations": {
          "percentTime": 0
        },
        "counts": {
          "resultCount": 1
        }
      },
      {
        // This operation represents the serialization and preparation for a result from 
        // the preceding graph operations. The metrics include: time, percentTime of total 
        // execution time and resultCount.
        "name": "ProjectOperator",
        "time": 0,
        "annotations": {
          "percentTime": 0
        },
        "counts": {
          "resultCount": 1
        }
      }
    ]
  }
]

Poznámka:

Krok executionProfile spustí dotaz Gremlin. To zahrnuje kroky addV addEnebo kroky, které způsobí vytvoření a potvrdí změny zadané v dotazu. V důsledku toho se budou účtovat také jednotky žádostí vygenerované dotazem Gremlin.

Objekty odpovědi profilu spuštění

Odpověď funkce executionProfile() vrátí hierarchii objektů JSON s následující strukturou:

  • Objekt operace Gremlin: Představuje celou operaci Gremlin, která byla provedena. Obsahuje následující vlastnosti.

    • gremlin: Explicitní příkaz Gremlin, který byl proveden.
    • totalTime: Čas v milisekundách, kdy provádění kroku vzniklo.
    • metrics: Pole, které obsahuje všechny operátory modulu runtime služby Cosmos DB, které byly provedeny za účelem splnění dotazu. Tento seznam je seřazený v pořadí provádění.
  • Operátory modulu runtime Služby Cosmos DB: Představuje všechny komponenty celé operace Gremlin. Tento seznam je seřazený v pořadí provádění. Každý objekt obsahuje následující vlastnosti:

    • name: Název operátoru. Toto je typ kroku, který byl vyhodnocen a proveden. Další informace najdete v následující tabulce.
    • time: Doba trvání daného operátoru v milisekundách.
    • annotations: Obsahuje další informace specifické pro operátor, který byl proveden.
    • annotations.percentTime: Procento celkové doby, kterou trvalo spuštění konkrétního operátoru.
    • counts: Počet objektů vrácených z vrstvy úložiště tímto operátorem. Tato hodnota je obsažena ve skalární hodnotě counts.resultCount v rámci.
    • storeOps: Představuje operaci úložiště, která může zahrnovat jeden nebo více oddílů.
    • storeOps.fanoutFactor: Představuje počet oddílů, ke kterým tato konkrétní operace úložiště přistupovala.
    • storeOps.count: Představuje počet výsledků, které tato operace úložiště vrátila.
    • storeOps.size: Představuje velikost v bajtech výsledku dané operace úložiště.
Operátor modulu runtime Gremlin služby Cosmos DB Popis
GetVertices Tento krok získá predikovanou sadu objektů z vrstvy trvalosti.
GetEdges Tento krok získá hrany, které sousedí se sadou vrcholů. Tento krok může vést k jedné nebo mnoha operacím úložiště.
GetNeighborVertices Tento krok získá vrcholy, které jsou připojeny k sadě hran. Hrany obsahují klíče oddílu a ID jejich zdrojových i cílových vrcholů.
Coalesce Tento krok odpovídá vyhodnocení dvou operací při každém coalesce() spuštění kroku Gremlin.
CartesianProductOperator Tento krok vypočítá kartézský součin mezi dvěma datovými sadami. Obvykle se provádí při každém použití predikátů to() nebo from() použití.
ConstantSourceOperator Tento krok vypočítá výraz, který v důsledku toho vytvoří konstantní hodnotu.
ProjectOperator Tento krok připraví a serializuje odpověď pomocí výsledku předchozích operací.
ProjectAggregation Tento krok připraví a serializuje odpověď pro agregační operaci.

Poznámka:

Tento seznam bude i nadále aktualizován, jakmile se přidají nové operátory.

Příklady analýzy odpovědi profilu spuštění

Tady jsou příklady běžných optimalizací, které je možné odhalit pomocí odpovědi profilu spuštění:

  • Nevidomý dotaz na ventilátor.
  • Nefiltrovaný dotaz

Vzory dotazů nevidomých ventilátorů

Předpokládejme následující odpověď profilu spuštění z děleného grafu:

[
  {
    "gremlin": "g.V('tt0093640').executionProfile()",
    "totalTime": 46,
    "metrics": [
      {
        "name": "GetVertices",
        "time": 46,
        "annotations": {
          "percentTime": 100
        },
        "counts": {
          "resultCount": 1
        },
        "storeOps": [
          {
            "fanoutFactor": 5,
            "count": 1,
            "size": 589,
            "time": 75.61
          }
        ]
      },
      {
        "name": "ProjectOperator",
        "time": 0,
        "annotations": {
          "percentTime": 0
        },
        "counts": {
          "resultCount": 1
        }
      }
    ]
  }
]

Z toho lze učinit následující závěry:

  • Dotaz je vyhledávání s jedním ID, protože příkaz Gremlin se řídí vzorem g.V('id').
  • Vzhledem k time metrikě se zdá, že latence tohoto dotazu je vysoká, protože se jedná o více než 10 ms pro operaci čtení s jedním bodem.
  • Když se podíváme na storeOps objekt, vidíme, že fanoutFactor je 5to , což znamená, že k 5 oddílům se přistupovalo touto operací.

Na závěr této analýzy můžeme zjistit, že první dotaz přistupuje k více oddílům, než je potřeba. Tento problém lze vyřešit zadáním klíče dělení v dotazu jako predikátu. To povede k nižší latenci a nižším nákladům na dotaz. Přečtěte si další informace o dělení grafu. Optimaličtější dotaz by byl g.V('tt0093640').has('partitionKey', 't1001').

Nefiltrované vzory dotazů

Porovnejte následující dvě odpovědi profilu spuštění. Pro zjednodušení tyto příklady používají jeden dělený graf.

Tento první dotaz načte všechny vrcholy s popiskem tweet a pak získá jejich sousední vrcholy:

[
  {
    "gremlin": "g.V().hasLabel('tweet').out().executionProfile()",
    "totalTime": 42,
    "metrics": [
      {
        "name": "GetVertices",
        "time": 31,
        "annotations": {
          "percentTime": 73.81
        },
        "counts": {
          "resultCount": 30
        },
        "storeOps": [
          {
            "fanoutFactor": 1,
            "count": 13,
            "size": 6819,
            "time": 1.02
          }
        ]
      },
      {
        "name": "GetEdges",
        "time": 6,
        "annotations": {
          "percentTime": 14.29
        },
        "counts": {
          "resultCount": 18
        },
        "storeOps": [
          {
            "fanoutFactor": 1,
            "count": 20,
            "size": 7950,
            "time": 1.98
          }
        ]
      },
      {
        "name": "GetNeighborVertices",
        "time": 5,
        "annotations": {
          "percentTime": 11.9
        },
        "counts": {
          "resultCount": 20
        },
        "storeOps": [
          {
            "fanoutFactor": 1,
            "count": 4,
            "size": 1070,
            "time": 1.19
          }
        ]
      },
      {
        "name": "ProjectOperator",
        "time": 0,
        "annotations": {
          "percentTime": 0
        },
        "counts": {
          "resultCount": 20
        }
      }
    ]
  }
]

Před prozkoumáním sousedních vrcholů si všimněte profilu stejného dotazu, has('lang', 'en')ale teď s dalším filtrem:

[
  {
    "gremlin": "g.V().hasLabel('tweet').has('lang', 'en').out().executionProfile()",
    "totalTime": 14,
    "metrics": [
      {
        "name": "GetVertices",
        "time": 14,
        "annotations": {
          "percentTime": 58.33
        },
        "counts": {
          "resultCount": 11
        },
        "storeOps": [
          {
            "fanoutFactor": 1,
            "count": 11,
            "size": 4807,
            "time": 1.27
          }
        ]
      },
      {
        "name": "GetEdges",
        "time": 5,
        "annotations": {
          "percentTime": 20.83
        },
        "counts": {
          "resultCount": 18
        },
        "storeOps": [
          {
            "fanoutFactor": 1,
            "count": 18,
            "size": 7159,
            "time": 1.7
          }
        ]
      },
      {
        "name": "GetNeighborVertices",
        "time": 5,
        "annotations": {
          "percentTime": 20.83
        },
        "counts": {
          "resultCount": 18
        },
        "storeOps": [
          {
            "fanoutFactor": 1,
            "count": 4,
            "size": 1070,
            "time": 1.01
          }
        ]
      },
      {
        "name": "ProjectOperator",
        "time": 0,
        "annotations": {
          "percentTime": 0
        },
        "counts": {
          "resultCount": 18
        }
      }
    ]
  }
]

Tyto dva dotazy dosáhly stejného výsledku, ale první z nich bude vyžadovat více jednotek žádostí, protože před dotazováním sousedních položek je potřeba iterovat větší počáteční datovou sadu. Při porovnávání následujících parametrů z obou odpovědí vidíme indikátory tohoto chování:

  • Hodnota metrics[0].time je vyšší v první odpovědi, což značí, že vyřešení tohoto jediného kroku trvalo déle.
  • Hodnota metrics[0].counts.resultsCount je vyšší i v první odpovědi, která indikuje, že počáteční pracovní datová sada byla větší.

Další kroky

  • Seznamte se s podporovanými funkcemi Gremlin ve službě Azure Cosmos DB.
  • Přečtěte si další informace o rozhraní Gremlin API ve službě Azure Cosmos DB.