Gremlin sorgularınızı hesaplamak için yürütme profili adımını kullanma

Uygulama hedefı: Gremlin API

Bu makale, Azure Cosmos DB Gremlin API’si graf veritabanları için yürütme profilini kullanma adımı için bir genel bakış sunar. Bu adım, sorun giderme ve sorgu iyileştirmeleri için ilgili bilgileri sağlar ve Cosmos DB Gremlin API’si hesabında yürütülebilen tüm Gremlin sorgularıyla uyumludur.

Bu adımı kullanmak için executionProfile() gremlin sorgunun sonuna işlev çağrısını eklemeniz gerekir. Gremlin sorgunuz yürütülür ve işlem sonucunda sorgu yürütme profiline sahip bir JSON yanıt nesnesi döner.

Örnek:

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

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

Adımı çağıran yanıt, yürütülen Gremlin adımını, geçen toplam zamanı ve deyiminin sonuç verdiği Cosmos DB çalışma zamanı işleçlerinin dizisini içeren bir executionProfile() JSON nesnesi olacaktır.

Not

Yürütme Profili için bu uygulama Apache Tinkerpop belirtimsinde tanımlanmamıştır. Bu, Azure Cosmos DB Gremlin API'sini uygulamasına özeldir.

Yanıt Örneği

Aşağıda, döndürülecek çıkışın açıklamalı bir örneği ve ardından ve ve ardından gelir:

Not

Bu örnek, yanıtın genel yapısını açıklayan açıklamalarla açıklama ek açıklamalarına sahiptir. Gerçek bir executionProfile yanıtı herhangi bir açıklama içermez.

[
  {
    // 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
        }
      }
    ]
  }
]

Not

executionProfile adımı Gremlin sorgusunu yürütür. Bu, addV oluşturma addE işlemiyle sonuçlanacak ve sorguda belirtilen değişiklikleri işecek veya adımlarını içerir. Sonuç olarak Gremlin sorgusu tarafından oluşturulan İstek Birimleri de ücret tahsil edilecektir.

Yürütme profili yanıt nesneleri

ExecutionProfile() işlevinin yanıtı, aşağıdaki yapıya sahip JSON nesnelerinin hiyerarşisini verir:

  • Gremlin işlem nesnesi: Yürütülen Gremlin işlemi tamamını temsil eder. Aşağıdaki özellikleri içerir.

    • gremlin: Yürütülen açık Gremlin deyimi.
    • totalTime: Adımın yürütülmesinin tahakkuk aldığı süre (milisaniye cinsinden).
    • metrics: Sorguyu gerçekleştirmek için yürütülen Cosmos DB çalışma zamanı işleçlerinin her birini içeren bir dizi. Bu liste yürütme sırasına göre sıralanmış.
  • Cosmos DB çalışma zamanı işleçleri: Tüm Gremlin işlemi bileşenlerini temsil eder. Bu liste yürütme sırasına göre sıralanmış. Her nesne aşağıdaki özellikleri içerir:

    • name: İşlecinin adı. Bu, değerlendirilen ve yürütülen adımın t t tür. Aşağıdaki tabloda daha fazla bilgi bulabilirsiniz.
    • time: Belirli bir işlecin aldığı milisaniye cinsinden süre.
    • annotations: Yürütülen işlecine özgü ek bilgiler içerir.
    • annotations.percentTime: Belirli bir işleci yürütmek için geçen toplam sürenin yüzdesi.
    • counts: Bu işleç tarafından depolama katmanından döndürülen nesne sayısı. Bu, içindeki counts.resultCount skaler değerde yer alan değerdir.
    • storeOps: Bir veya birden çok bölüme yayma işlemi temsil eder.
    • storeOps.fanoutFactor: Bu belirli depolama işlemi tarafından erişilen bölüm sayısını temsil eder.
    • storeOps.count: Bu depolama işlemi tarafından döndürülen sonuç sayısını temsil eder.
    • storeOps.size: Belirli bir depolama işlemi sonucunda elde edilen bayt cinsinden boyutu temsil eder.
Cosmos DB Gremlin Çalışma Zamanı İşleci Description
GetVertices Bu adım, kalıcılık katmanından önceden ayarlanmış bir nesne kümesi elde eder.
GetEdges Bu adım, bir köşe kümesine bitişik olan kenarları elde edilir. Bu adım bir veya daha fazla depolama işlemlerine neden olabilir.
GetNeighborVertices Bu adım, bir kenar kümesine bağlı olan köşeleri elde edilir. Kenarlar hem kaynak hem de hedef köşelerinin bölüm anahtarlarını ve kimliklerini içerir.
Coalesce Bu adım, Gremlin adımı her yürütülürken iki coalesce() işlemlerin değerlendirilmesini hesaplar.
CartesianProductOperator Bu adım, iki veri kümesi arasındaki kartesyen ürünü hesaplar. Genellikle veya kullanılan her durum için to() from() yürütülür.
ConstantSourceOperator Bu adım, sonuç olarak sabit bir değer üretmek için bir ifadeyi hesaplar.
ProjectOperator Bu adım, önceki işlemlerin sonucu kullanılarak bir yanıtı hazırlar ve seri hale getirmektedir.
ProjectAggregation Bu adım bir toplama işlemi için bir yanıtı hazırlar ve seri hale getirmez.

Not

Yeni işleçler eklendikça bu liste güncelleştirilecek.

Yürütme profili yanıtını analiz etme örnekleri

Aşağıda, Yürütme Profili yanıtı kullanılarak tespit edilen yaygın iyileştirme örnekleri verilmiştir:

  • Kör bir fanatiğin sorgusu.
  • Filtrelenmemiş sorgu.

Kör fanatiğin sorgu desenleri

Bölümlenmiş bir grafikten aşağıdaki yürütme profili yanıtını varsayabilirsiniz:

[
  {
    "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
        }
      }
    ]
  }
]

Bundan aşağıdaki sonuçlar çıkar:

  • Gremlin deyimi desenini takip eden sorgu tek bir kimlik g.V('id') aramasıdır.
  • Ölçümden anlaşılan, tek bir okuma noktası işlemi için time 10m'den fazla olduğu için bu sorgunun gecikme süresi yüksek gibi görünüyor.
  • nesnesine bakarak olduğunu görebiliriz. Başka bir ifadeyle bu işlem storeOps fanoutFactor 5 5 bölüme erişildi.

Bu analizin sonucu olarak, ilk sorgunun gerekenden fazla bölüme erişirken olduğunu belirleyebilirsiniz. Bu, sorguda bölümleme anahtarı bir durum olarak belirterek çözülebilirsiniz. Bu, daha az gecikme süresine ve sorgu başına daha az maliyete neden olur. Graf bölümleme hakkında daha fazla bilgi. Daha iyi bir sorgu g.V('tt0093640').has('partitionKey', 't1001') olabilir.

Filtrelenmemiş sorgu desenleri

Aşağıdaki iki yürütme profili yanıtını karşılaştırın. Kolaylık olması için bu örnekler tek bir bölümlenmiş graf kullanır.

Bu ilk sorgu etiketine sahip tüm köşeleri ve ardından tweet komşu köşelerini elde ediyor:

[
  {
    "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
        }
      }
    ]
  }
]

Bitişik köşeleri keşfetmeden önce, aynı sorgunun profiline dikkat ancak şimdi ek bir has('lang', 'en') filtreyle :

[
  {
    "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
        }
      }
    ]
  }
]

Ancak bu iki sorgu aynı sonuçla ulaşsa da, bitişik öğeleri sorgulamadan önce daha büyük bir ilk veri kümesinde yinelen gerektiğinden ilk sorgu daha fazla İstek Birimi gerektirir. Her iki yanıttan aşağıdaki parametreleri karşılaştırırken bu davranışın göstergelerini görebiliriz:

  • İlk metrics[0].time yanıtta değeri daha yüksektir ve bu da bu tek adımın çözülmesinin daha uzun zaman alalı olduğunu gösterir.
  • İlk metrics[0].counts.resultsCount çalışan veri kümesi daha büyük olduğunu gösteren ilk yanıtta da değer daha yüksektir.

Sonraki adımlar