Megosztás a következőn keresztül:


SQL-lekérdezés-végrehajtási metrikák lekérése és lekérdezési teljesítmény elemzése a .NET SDK használatával

A KÖVETKEZŐRE VONATKOZIK: NoSQL

Ez a cikk bemutatja, hogyan profilozza az SQL-lekérdezés teljesítményét az Azure Cosmos DB-ben a .NET SDK-ból lekért ServerSideCumulativeMetrics használatával. ServerSideCumulativeMetrics egy erősen beírt objektum, amely információkat tartalmaz a háttérbeli lekérdezések végrehajtásáról. Kumulatív metrikákat tartalmaz, amelyek összesítve vannak a kérelem összes fizikai partíciója között, az egyes fizikai partíciók metrikáinak listája és a kérelem teljes díja. Ezek a metrikák részletesebben is dokumentálva vannak a Lekérdezési teljesítmény finomhangolása című cikkben.

Lekérdezésmetrikák megállapítása

A lekérdezési metrikák erősen beírt objektumként érhetők el a .NET SDK-ban a 3.36.0-s verziótól kezdve. A verzió előtt, vagy ha másik SDK-nyelvet használ, a lekérdezési metrikákat a Diagnosticslekérdezési metrikák elemzésével kérdezheti le. Az alábbi kódminta bemutatja, hogyan kérhető le ServerSideCumulativeMetrics a FeedResponse-ből:Diagnostics

CosmosClient client = new CosmosClient(myCosmosEndpoint, myCosmosKey);
Container container = client.GetDatabase(myDatabaseName).GetContainer(myContainerName);

QueryDefinition query = new QueryDefinition("SELECT TOP 5 * FROM c");
FeedIterator<MyClass> feedIterator = container.GetItemQueryIterator<MyClass>(query);

while (feedIterator.HasMoreResults)
{
    // Execute one continuation of the query
    FeedResponse<MyClass> feedResponse = await feedIterator.ReadNextAsync();

    // Retrieve the ServerSideCumulativeMetrics object from the FeedResponse
    ServerSideCumulativeMetrics metrics = feedResponse.Diagnostics.GetQueryMetrics();
}

Lekérdezési metrikákat is lekérhet egy FeedResponse LINQ-lekérdezésből a ToFeedIterator() következő módszerrel:

FeedIterator<MyClass> feedIterator = container.GetItemLinqQueryable<MyClass>()
    .Take(5)
    .ToFeedIterator();

while (feedIterator.HasMoreResults)
{
    FeedResponse<MyClass> feedResponse = await feedIterator.ReadNextAsync();
    ServerSideCumulativeMetrics metrics = feedResponse.Diagnostics.GetQueryMetrics();
}

Kumulatív metrikák

ServerSideCumulativeMetrics Olyan tulajdonságot CumulativeMetrics tartalmaz, amely az egyirányú út összes partíciójára összesített lekérdezési metrikákat jelöli.

// Retrieve the ServerSideCumulativeMetrics object from the FeedResponse
ServerSideCumulativeMetrics metrics = feedResponse.Diagnostics.GetQueryMetrics();

// CumulativeMetrics is the metrics for this continuation aggregated over all partitions
ServerSideMetrics cumulativeMetrics = metrics.CumulativeMetrics;

Ezeket a metrikákat a lekérdezés összes körútja során is összesítheti. Az alábbi példa bemutatja, hogyan összesítheti a lekérdezések végrehajtási idejét egy adott lekérdezés összes körútja során a LINQ használatával:

QueryDefinition query = new QueryDefinition("SELECT TOP 5 * FROM c");
FeedIterator<MyClass> feedIterator = container.GetItemQueryIterator<MyClass>(query);

List<ServerSideCumulativeMetrics> metrics = new List<ServerSideCumulativeMetrics>();
TimeSpan cumulativeTime;
while (feedIterator.HasMoreResults)
{
    // Execute one continuation of the query
    FeedResponse<MyClass> feedResponse = await feedIterator.ReadNextAsync();

    // Store the ServerSideCumulativeMetrics object to aggregate values after all round trips
    metrics.Add(feedResponse.Diagnostics.GetQueryMetrics());
}

// Aggregate values across trips for metrics of interest
TimeSpan totalTripsExecutionTime = metrics.Aggregate(TimeSpan.Zero, (currentSum, next) => currentSum + next.CumulativeMetrics.TotalTime);
DoSomeLogging(totalTripsExecutionTime);

Particionált metrikák

ServerSideCumulativeMetrics olyan tulajdonságot PartitionedMetrics tartalmaz, amely az oda-vissza út partíciónkénti metrikáinak listája. Ha több fizikai partíciót ér el egyetlen oda-visszaúton, akkor az egyes partíciók metrikái megjelennek a listában. A particionált metrikák ServerSidePartitionedMetricsként jelennek meg, amelyek egyedi azonosítót adnak az egyes fizikai partíciókhoz, és kérnek díjat az adott partícióhoz.

// Retrieve the ServerSideCumulativeMetrics object from the FeedResponse
ServerSideCumulativeMetrics metrics = feedResponse.Diagnostics.GetQueryMetrics();

// PartitionedMetrics is a list of per-partition metrics for this continuation
List<ServerSidePartitionedMetrics> partitionedMetrics = metrics.PartitionedMetrics;

Ha az összes körút során halmozódik fel, a partíciónkénti metrikák lehetővé teszik annak megtekintését, hogy egy adott partíció teljesítményproblémákat okoz-e másokhoz képest. Az alábbi példa bemutatja, hogyan csoportosíthatja az egyes utak partíciómetrikáit a LINQ használatával:

QueryDefinition query = new QueryDefinition("SELECT TOP 5 * FROM c");
FeedIterator<MyClass> feedIterator = container.GetItemQueryIterator<MyClass>(query);

List<ServerSideCumulativeMetrics> metrics = new List<ServerSideCumulativeMetrics>();
while (feedIterator.HasMoreResults)
{
    // Execute one continuation of the query
    FeedResponse<MyClass> feedResponse = await feedIterator.ReadNextAsync();

    // Store the ServerSideCumulativeMetrics object to aggregate values after all round trips
    metrics.Add(feedResponse.Diagnostics.GetQueryMetrics());
}

// Group metrics by partition key range id
var groupedPartitionMetrics = metrics.SelectMany(m => m.PartitionedMetrics).GroupBy(p => p.PartitionKeyRangeId);
foreach(var partitionGroup in groupedPartitionMetrics)
{
    foreach(var tripMetrics in partitionGroup)
    {
        DoSomethingWithMetrics();
    }
}

A lekérdezési kérelem díjának lekérése

Az egyes lekérdezések által felhasznált kérelemegységeket rögzítheti a költséges lekérdezések vagy a nagy átviteli sebességet használó lekérdezések vizsgálatához. A teljes kérelemdíj lekérhető a tulajdonság használatával, TotalRequestCharge vagy megtekintheti az egyes partíciók kérelemdíját az RequestCharge egyes ServerSidePartitionedMetrics visszaadott tulajdonságok használatával.ServerSideCumulativeMetrics

A kérelem teljes díja a következő tulajdonság használatával is elérhető: .</a0RequestCharge> Ha többet szeretne megtudni arról, hogyan kérheti le a kérelem díját az Azure Portalon és a különböző SDK-kban, tekintse meg a kérelemegységek díjáról szóló cikket.

QueryDefinition query = new QueryDefinition("SELECT TOP 5 * FROM c");
FeedIterator<MyClass> feedIterator = container.GetItemQueryIterator<MyClass>(query);

while (feedIterator.HasMoreResults)
{
    // Execute one continuation of the query
    FeedResponse<MyClass> feedResponse = await feedIterator.ReadNextAsync();
    double requestCharge = feedResponse.RequestCharge;

    // Log the RequestCharge how ever you want.
    DoSomeLogging(requestCharge);
}

A lekérdezés végrehajtási idejének lekérése

A lekérdezési metrikákból minden egyes úthoz rögzítheti a lekérdezések végrehajtási idejét. A kérelmek késésének vizsgálatakor fontos megkülönböztetni a lekérdezések végrehajtási idejét más késési forrásoktól, például a hálózati átviteli időtől. Az alábbi példa bemutatja, hogyan kérhet le kumulatív lekérdezésvégrehajtási időt minden egyes körúthoz:

QueryDefinition query = new QueryDefinition("SELECT TOP 5 * FROM c");
FeedIterator<MyClass> feedIterator = container.GetItemQueryIterator<MyClass>(query);

TimeSpan cumulativeTime;
while (feedIterator.HasMoreResults)
{
    // Execute one continuation of the query
    FeedResponse<MyClass> feedResponse = await feedIterator.ReadNextAsync();
    ServerSideCumulativeMetrics metrics = response.Diagnostics.GetQueryMetrics();
    cumulativeTime = metrics.CumulativeMetrics.TotalTime;
}

// Log the elapsed time
DoSomeLogging(cumulativeTime);

Az index kihasználtságának lekérése

Az index kihasználtságának megtekintése segíthet a lassú lekérdezések hibakeresésében. Azok a lekérdezések, amelyek nem tudják használni az indexet, az eredményhalmaz visszaadása előtt a tároló összes dokumentumának teljes vizsgálata következik be.

Íme egy példa egy vizsgálati lekérdezésre:

SELECT VALUE c.description 
FROM   c 
WHERE UPPER(c.description) = "BABYFOOD, DESSERT, FRUIT DESSERT, WITHOUT ASCORBIC ACID, JUNIOR"

A lekérdezés szűrője az UPPER rendszerfüggvényt használja, amely nem az indexből származik. A lekérdezés nagy gyűjteményen való végrehajtása az alábbi lekérdezési metrikákat eredményezte az első folytatáshoz:

QueryMetrics

Retrieved Document Count                 :          60,951
Retrieved Document Size                  :     399,998,938 bytes
Output Document Count                    :               7
Output Document Size                     :             510 bytes
Index Utilization                        :            0.00 %
Total Query Execution Time               :        4,500.34 milliseconds
Query Preparation Time                   :             0.2 milliseconds
Index Lookup Time                        :            0.01 milliseconds
Document Load Time                       :        4,177.66 milliseconds
Runtime Execution Time                   :           407.9 milliseconds
Document Write Time                      :            0.01 milliseconds

Figyelje meg a lekérdezési metrikák kimenetének alábbi értékeit:

Retrieved Document Count                 :          60,951
Retrieved Document Size                  :     399,998,938 bytes

Ez a lekérdezés 60 951 dokumentumot töltött be, összesen 399 998 938 bájtot. A ennyi bájt betöltése magas költséggel jár, vagy a kérelemegység díja. A lekérdezés végrehajtása is hosszú időt vesz igénybe, ami a teljes eltöltött idő tulajdonsággal egyértelmű:

Total Query Execution Time               :        4,500.34 milliseconds

Ez azt jelenti, hogy a lekérdezés végrehajtása 4,5 másodpercig tartott (és ez csak egy folytatás volt).

A példa lekérdezés optimalizálásához kerülje az UPPER használatát a szűrőben. Ehelyett a dokumentumok létrehozásakor vagy frissítésekor az c.description értékeket minden nagybetűbe be kell szúrni. A lekérdezés ezután a következő lesz:

SELECT VALUE c.description 
FROM   c 
WHERE c.description = "BABYFOOD, DESSERT, FRUIT DESSERT, WITHOUT ASCORBIC ACID, JUNIOR"

Ez a lekérdezés mostantól kiszolgálható az indexből. Másik lehetőségként számítási tulajdonságok használatával indexelheti a rendszerfüggvények vagy összetett számítások eredményeit, amelyek egyébként teljes vizsgálatot eredményeznének.

A lekérdezés teljesítményének finomhangolásáról a Lekérdezési teljesítmény finomhangolása című cikkben talál további információt.

Hivatkozások

Következő lépések