Justera frågeprestanda med Azure Cosmos DB
GÄLLER FÖR:
SQL API
Azure Cosmos DB tillhandahåller ett SQL API för att köra frågor mot data, utan att det krävs schema eller sekundära index. Den här artikeln innehåller följande information för utvecklare:
- Detaljerad information om hur Azure Cosmos DB är SQL frågekörning fungerar
- Information om frågebegärande- och svarshuvuden och klient-SDK-alternativ
- Tips och metodtips för frågeprestanda
- Exempel på hur du använder SQL för att felsöka frågeprestanda
Om SQL frågekörning
I Azure Cosmos DB kan du lagra data i containrar, som kan växa till valfri lagringsstorlek eller begära dataflöde. Azure Cosmos DB skalar sömlöst data över fysiska partitioner under skalan för att hantera datatillväxt eller ökning i etablerat dataflöde. Du kan skicka SQL frågor till valfri container med hjälp av REST API eller någon av de SQL-SDK:er som stöds.
En kort översikt över partitionering: du definierar en partitionsnyckel som "stad", som avgör hur data delas upp mellan fysiska partitioner. Data som hör till en enda partitionsnyckel (till exempel "stad" == "Seattle") lagras inom en fysisk partition, men vanligtvis har en enda fysisk partition flera partitionsnycklar. När en partition når sin lagringsstorlek delar tjänsten sömlöst upp partitionen i två nya partitioner och delar upp partitionsnyckeln jämnt över dessa partitioner. Eftersom partitioner är tillfälliga använder API:erna en abstraktion av ett "partitionsnyckelintervall", som anger intervallen med partitionsnyckelhash-värden.
När du utfärdar en fråga Azure Cosmos DB utför SDK följande logiska steg:
- Parsa SQL för att fastställa frågekörningsplanen.
- Om frågan innehåller ett filter mot partitionsnyckeln, till
SELECT * FROM c WHERE c.city = "Seattle"exempel , dirigeras den till en enda partition. Om frågan inte har något filter på partitionsnyckeln körs den i alla partitioner och resultatet sammanfogas på klientsidan. - Frågan körs inom varje partition i serie eller parallellt, baserat på klientkonfigurationen. Inom varje partition kan frågan göra en eller flera turer fram och retur beroende på frågans komplexitet, konfigurerad sidstorlek och etablerat dataflöde för samlingen. Varje körning returnerar antalet enheter för programbegäran som förbrukas av frågekörning och eventuellt frågekörningsstatistik.
- SDK:n utför en sammanfattning av frågeresultatet över partitioner. Om frågan till exempel omfattar en ORDER BY över partitioner sammanfogas resultat från enskilda partitioner för att returnera resultat i globalt sorterad ordning. Om frågan är en aggregering som summeras antalet från enskilda
COUNTpartitioner för att skapa det totala antalet.
I DEDK:erna finns olika alternativ för frågekörning. I .NET är dessa alternativ till exempel tillgängliga i FeedOptions klassen . I följande tabell beskrivs dessa alternativ och hur de påverkar frågekörningstiden.
| Alternativ | Beskrivning |
|---|---|
EnableCrossPartitionQuery |
Måste anges till true för alla frågor som måste köras över mer än en partition. Det här är en explicit flagga som gör att du kan kompromissa med medvetna prestanda under utvecklingstiden. |
EnableScanInQuery |
Måste vara inställt på sant om du har valt bort indexering, men ändå vill köra frågan via en genomsökning. Gäller endast om indexering för den begärda filtersökvägen är inaktiverad. |
MaxItemCount |
Det maximala antalet objekt som ska returneras per tur och retur till servern. Genom att ange till -1 kan du låta servern hantera antalet objekt. Eller så kan du sänka det här värdet om du bara vill hämta ett litet antal objekt per tur och retur. |
MaxBufferedItemCount |
Det här är ett alternativ på klientsidan som används för att begränsa minnesförbrukningen när du utför ORDER BY mellan partitioner. Ett högre värde hjälper till att minska svarstiden vid sortering mellan partitioner. |
MaxDegreeOfParallelism |
Hämtar eller anger antalet samtidiga åtgärder som körs på klientsidan vid parallell frågekörning i Azure Cosmos-databastjänsten. Ett positivt egenskapsvärde begränsar antalet samtidiga åtgärder till det inställda värdet. Om det är inställt på mindre än 0 avgör systemet automatiskt antalet samtidiga åtgärder som ska köras. |
PopulateQueryMetrics |
Möjliggör detaljerad loggning av statistik över tid som ägnats i olika faser av frågekörning som kompileringstid, indexlooptid och dokumentbelastningstid. Du kan dela utdata från frågestatistik med Azure Support diagnostisera problem med frågeprestanda. |
RequestContinuation |
Du kan återuppta frågekörningen genom att skicka den täckande fortsättningstoken som returneras av en fråga. Fortsättningstoken kapslar in alla tillstånd som krävs för frågekörning. |
ResponseContinuationTokenLimitInKb |
Du kan begränsa den maximala storleken för fortsättningstoken som returneras av servern. Du kan behöva ange detta om programvärden har begränsningar för storleken på svarshuvuden. Om du anger detta kan den totala varaktigheten och antalet RU:er som förbrukas för frågan ökas. |
Låt oss till exempel ta en exempelfråga på partitionsnyckeln som begärdes i en samling med som partitionsnyckel och etablerade med /city 100 000 RU/s av dataflödet. Du begär den här frågan CreateDocumentQuery<T> med hjälp av i .NET enligt följande:
IDocumentQuery<dynamic> query = client.CreateDocumentQuery(
UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName),
"SELECT * FROM c WHERE c.city = 'Seattle'",
new FeedOptions
{
PopulateQueryMetrics = true,
MaxItemCount = -1,
MaxDegreeOfParallelism = -1,
EnableCrossPartitionQuery = true
}).AsDocumentQuery();
FeedResponse<dynamic> result = await query.ExecuteNextAsync();
SDK-kodfragmentet som visas ovan motsvarar följande REST API begäran:
POST https://arramacquerymetrics-westus.documents.azure.com/dbs/db/colls/sample/docs HTTP/1.1
x-ms-continuation:
x-ms-documentdb-isquery: True
x-ms-max-item-count: -1
x-ms-documentdb-query-enablecrosspartition: True
x-ms-documentdb-query-parallelizecrosspartitionquery: True
x-ms-documentdb-query-iscontinuationexpected: True
x-ms-documentdb-populatequerymetrics: True
x-ms-date: Tue, 27 Jun 2017 21:52:18 GMT
authorization: type%3dmaster%26ver%3d1.0%26sig%3drp1Hi83Y8aVV5V6LzZ6xhtQVXRAMz0WNMnUuvriUv%2b4%3d
x-ms-session-token: 7:8,6:2008,5:8,4:2008,3:8,2:2008,1:8,0:8,9:8,8:4008
Cache-Control: no-cache
x-ms-consistency-level: Session
User-Agent: documentdb-dotnet-sdk/1.14.1 Host/32-bit MicrosoftWindowsNT/6.2.9200.0
x-ms-version: 2017-02-22
Accept: application/json
Content-Type: application/query+json
Host: arramacquerymetrics-westus.documents.azure.com
Content-Length: 52
Expect: 100-continue
{"query":"SELECT * FROM c WHERE c.city = 'Seattle'"}
Varje frågekörningssida motsvarar en REST API med rubriken och SQL POST Accept: application/query+json frågan i brödtexten. Varje fråga gör en eller flera tur och retur-resor till servern med x-ms-continuation den token som returneras mellan klienten och servern för att återuppta körningen. Konfigurationsalternativen i FeedOptions skickas till servern i form av begärandehuvuden. Motsvarar till MaxItemCount exempel x-ms-max-item-count .
Begäran returnerar följande svar (trunkerat för läsbarhet):
HTTP/1.1 200 Ok
Cache-Control: no-store, no-cache
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: application/json
Server: Microsoft-HTTPAPI/2.0
Strict-Transport-Security: max-age=31536000
x-ms-last-state-change-utc: Tue, 27 Jun 2017 21:01:57.561 GMT
x-ms-resource-quota: documentSize=10240;documentsSize=10485760;documentsCount=-1;collectionSize=10485760;
x-ms-resource-usage: documentSize=1;documentsSize=884;documentsCount=2000;collectionSize=1408;
x-ms-item-count: 2000
x-ms-schemaversion: 1.3
x-ms-alt-content-path: dbs/db/colls/sample
x-ms-content-path: +9kEANVq0wA=
x-ms-xp-role: 1
x-ms-documentdb-query-metrics: totalExecutionTimeInMs=33.67;queryCompileTimeInMs=0.06;queryLogicalPlanBuildTimeInMs=0.02;queryPhysicalPlanBuildTimeInMs=0.10;queryOptimizationTimeInMs=0.00;VMExecutionTimeInMs=32.56;indexLookupTimeInMs=0.36;documentLoadTimeInMs=9.58;systemFunctionExecuteTimeInMs=0.00;userFunctionExecuteTimeInMs=0.00;retrievedDocumentCount=2000;retrievedDocumentSize=1125600;outputDocumentCount=2000;writeOutputTimeInMs=18.10;indexUtilizationRatio=1.00
x-ms-request-charge: 604.42
x-ms-serviceversion: version=1.14.34.4
x-ms-activity-id: 0df8b5f6-83b9-4493-abda-cce6d0f91486
x-ms-session-token: 2:2008
x-ms-gatewayversion: version=1.14.33.2
Date: Tue, 27 Jun 2017 21:59:49 GMT
Huvudena för nyckelsvar som returneras från frågan innehåller följande:
| Alternativ | Beskrivning |
|---|---|
x-ms-item-count |
Antalet objekt som returneras i svaret. Detta beror på det angivna , antalet objekt som kan passas in i den maximala x-ms-max-item-count svarsnyttolastens storlek, det etablerade dataflödet och frågekörningstiden. |
x-ms-continuation: |
Fortsättningstoken för att återuppta körningen av frågan om ytterligare resultat är tillgängliga. |
x-ms-documentdb-query-metrics |
Frågestatistiken för körningen. Det här är en avgränsad sträng som innehåller statistik över tid som ägnats åt de olika faserna för frågekörning. Returneras x-ms-documentdb-populatequerymetrics om har angetts till True . |
x-ms-request-charge |
Antalet enheter för begäran som används av frågan. |
Mer information om REST API begärandehuvuden och alternativ finns i Fråga resurser med hjälp av REST API.
Metodtips för frågeprestanda
Följande är de vanligaste faktorerna som påverkar Azure Cosmos DB frågeprestanda. Vi går djupare in på vart och ett av dessa ämnen i den här artikeln.
| Faktor | Tips |
|---|---|
| Etablerat dataflöde | Mät RU per fråga och se till att du har det nödvändiga etablerade dataflödet för dina frågor. |
| Partitionering och partitionsnycklar | Prioritera frågor med partitionsnyckelvärdet i filtersatsen för låg latens. |
| SDK- och frågealternativ | Följ SDK:s metodtips som direktanslutning och finjustera alternativ för frågekörning på klientsidan. |
| Indexeringsprincip | Kontrollera att du har de indexeringssökvägar/policyer som krävs för frågan. |
| Frågekörningsmått | Analysera måtten för frågekörning för att identifiera potentiella omwrites av fråge- och dataformer. |
Etablerat dataflöde
I Cosmos DB skapar du containrar med data, var och en med reserverat dataflöde uttryckt i enheter för begäran (RU) per sekund. En läsning av ett dokument på 1 kB är 1 RU, och varje åtgärd (inklusive frågor) normaliseras till ett fast antal RU:er baserat på dess komplexitet. Om du till exempel har 1 000 RU/s etablerat för din container och du har en fråga som den som förbrukar 5 RU:er kan du utföra SELECT * FROM c WHERE c.city = 'Seattle' (1 000 RU/s) / (5 RU/fråga) = 200 frågor/s sådana frågor per sekund.
Om du skickar fler än 200 frågor per sekund startar tjänsten hastighetsbegränsningen för inkommande begäranden över 200/s. DE HÄRD:erna hanterar det här fallet automatiskt genom att utföra en backoff/återförsök, och därför kan du märka en högre svarstid för dessa frågor. Genom att öka det etablerade dataflödet till det nödvändiga värdet förbättras frågefördröjningen och dataflödet.
Mer information om enheter för begäran finns i Enheter för begäran.
Partitionering och partitionsnycklar
Med Azure Cosmos DB vanligtvis frågor i följande ordning från snabbaste/mest effektiva till långsammare/mindre effektiva.
- GET på en enskild partitionsnyckel och objektnyckel
- Fråga med en filtersats på en enda partitionsnyckel
- Fråga utan en likhets- eller intervallfiltersats för någon egenskap
- Fråga utan filter
Frågor som behöver kontakta alla partitioner behöver längre svarstider och kan använda högre RU:er. Eftersom varje partition har automatisk indexering mot alla egenskaper kan frågan betjänas effektivt från indexet i det här fallet. Du kan göra frågor som sträcker sig över partitioner snabbare med hjälp av alternativen för parallellitet.
Mer information om partitionering och partitionsnycklar finns i Partitionering i Azure Cosmos DB.
SDK- och frågealternativ
Se Prestandatestning Tips prestandatestning för att få bästa möjliga prestanda på klientsidan från Azure Cosmos DB. Detta omfattar användning av de senaste SDK:erna, konfiguration av plattformsspecifika konfigurationer som standardantal anslutningar, skräpinsamlingsfrekvens och användning av lätta anslutningsalternativ som Direct/TCP.
Maximalt antal objekt
För frågor kan värdet för ha en betydande inverkan på frågetiden från MaxItemCount slutet till slut. Varje tur och retur till servern returnerar högst antalet objekt i MaxItemCount (standardvärdet är 100 objekt). Om du anger ett högre värde (-1 är max och rekommenderas) förbättras frågevaraktigheten totalt genom att antalet turer fram och tillbaka mellan servern och klienten begränsas, särskilt för frågor med stora resultatmängder.
IDocumentQuery<dynamic> query = client.CreateDocumentQuery(
UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName),
"SELECT * FROM c WHERE c.city = 'Seattle'",
new FeedOptions
{
MaxItemCount = -1,
}).AsDocumentQuery();
Maximal grad av parallellitet
För frågor finjusterar du för att identifiera de bästa konfigurationerna för ditt program, särskilt om du utför frågor mellan partitioner (utan ett filter på MaxDegreeOfParallelism partitionsnyckelvärdet). MaxDegreeOfParallelism styr det maximala antalet parallella uppgifter, det vill säga det maximala antalet partitioner som ska besökas parallellt.
IDocumentQuery<dynamic> query = client.CreateDocumentQuery(
UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName),
"SELECT * FROM c WHERE c.city = 'Seattle'",
new FeedOptions
{
MaxDegreeOfParallelism = -1,
EnableCrossPartitionQuery = true
}).AsDocumentQuery();
Vi antar att
- D = Standard Maximalt antal parallella uppgifter (= totalt antal processorer på klientdatorn)
- P = Maximalt antal parallella uppgifter som angetts av användaren
- N = Antalet partitioner som behöver besökas för att besvara en fråga
Följande är effekterna av hur de parallella frågorna beter sig för olika värden för P.
- (P == 0) => serieläge
- (P == 1) => maxvärde för en uppgift
- (P > 1) => parallella uppgifter (P, N)
- (P < 1) => parallella uppgifter (N, D)
Information om SDK-versionsinformation och information om implementerade klasser och metoder finns i SQL SDK:er
Svarstid för nätverk
Se Azure Cosmos DB global distribution för hur du ställer in global distribution och ansluter till den närmaste regionen. Nätverksfördröjning har en betydande inverkan på frågeprestanda när du behöver göra flera turer eller hämta en stor resultatuppsättning från frågan.
Avsnittet om frågekörningsmått förklarar hur du hämtar serverns körningstid för frågor ( ), så att du kan skilja mellan tid som ägnats åt frågekörning och tid som spenderas totalExecutionTimeInMs under nätverksövergång.
Indexeringsprincip
Se Konfigurera indexeringsprincip för indexering av sökvägar, typer och lägen och hur de påverkar frågekörningen. Som standard använder indexeringsprincipen intervallindexering för strängar, vilket är effektivt för likhetsfrågor. Om du behöver intervallfrågor för strängar rekommenderar vi att du anger intervallindextypen för alla strängar.
Som standard Azure Cosmos DB automatiskt indexering för alla data. För infogningsscenarier med höga prestanda bör du överväga att exkludera sökvägar eftersom detta minskar RU-kostnaden för varje infogningsåtgärd.
Frågekörningsmått
Du kan hämta detaljerade mått om frågekörning genom att skicka in det valfria x-ms-documentdb-populatequerymetrics huvudet ( FeedOptions.PopulateQueryMetrics i .NET SDK). Värdet som returneras x-ms-documentdb-query-metrics i har följande nyckel/värde-par som är avsedda för avancerad felsökning av frågekörning.
IDocumentQuery<dynamic> query = client.CreateDocumentQuery(
UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName),
"SELECT * FROM c WHERE c.city = 'Seattle'",
new FeedOptions
{
PopulateQueryMetrics = true,
}).AsDocumentQuery();
FeedResponse<dynamic> result = await query.ExecuteNextAsync();
// Returns metrics by partition key range Id
IReadOnlyDictionary<string, QueryMetrics> metrics = result.QueryMetrics;
| Metric | Enhet | Description |
|---|---|---|
totalExecutionTimeInMs |
millisekunder | Frågekörningstid |
queryCompileTimeInMs |
millisekunder | Frågekompileringstid |
queryLogicalPlanBuildTimeInMs |
millisekunder | Tid för att skapa en logisk frågeplan |
queryPhysicalPlanBuildTimeInMs |
millisekunder | Tid för att skapa en fysisk frågeplan |
queryOptimizationTimeInMs |
millisekunder | Tid som ägnats åt att optimera frågan |
VMExecutionTimeInMs |
millisekunder | Tid som ägnats åt frågekörning |
indexLookupTimeInMs |
millisekunder | Tid som ägnats åt fysiskt indexlager |
documentLoadTimeInMs |
millisekunder | Tid som ägnats åt att läsa in dokument |
systemFunctionExecuteTimeInMs |
millisekunder | Total tid som ägnats åt att köra systemfunktioner (inbyggda) i millisekunder |
userFunctionExecuteTimeInMs |
millisekunder | Total tid som ägnats åt att köra användardefinierade funktioner i millisekunder |
retrievedDocumentCount |
count | Totalt antal hämtade dokument |
retrievedDocumentSize |
Byte | Total storlek på hämtade dokument i byte |
outputDocumentCount |
count | Antal utdatadokument |
writeOutputTimeInMs |
millisekunder | Tid som läggs på att skriva utdata i millisekunder |
indexUtilizationRatio |
ratio (<=1) | Förhållandet mellan antalet dokument som matchas av filtret och antalet inlästa dokument |
Klient-SDK:erna kan internt göra flera frågeåtgärder för att hantera frågan inom varje partition. Klienten gör mer än ett anrop per partition om det totala resultatet överskrider , om frågan överskrider det etablerade dataflödet för partitionen, eller om frågenyttolasten når den maximala storleken per sida, eller om frågan når den system allokerade x-ms-max-item-count tidsgränsen. Varje partiell frågekörning returnerar en x-ms-documentdb-query-metrics för den sidan.
Här är några exempelfrågor och hur du tolkar några av de mått som returneras från frågekörningen:
| Söka i data | Exempelmått | Description |
|---|---|---|
SELECT TOP 100 * FROM c |
"RetrievedDocumentCount": 101 |
Antalet dokument som hämtas är 100 +1 för att matcha TOP-satsen. Frågetiden spenderas huvudsakligen WriteOutputTime i och eftersom det är en DocumentLoadTime genomsökning. |
SELECT TOP 500 * FROM c |
"RetrievedDocumentCount": 501 |
RetrievedDocumentCount är nu högre (500+1 för att matcha TOP-satsen). |
SELECT * FROM c WHERE c.N = 55 |
"IndexLookupTime": "00:00:00.0009500" |
Cirka 0,9 ms används i IndexLookupTime för en nyckeluppslag, eftersom det är en indexuppslag på /N/? . |
SELECT * FROM c WHERE c.N > 55 |
"IndexLookupTime": "00:00:00.0017700" |
Lite mer tid (1,7 ms) som spenderas i IndexLookupTime över en intervallgenomsökning, eftersom det är en indexsökning på /N/? . |
SELECT TOP 500 c.N FROM c |
"IndexLookupTime": "00:00:00.0017700" |
Samma tid som DocumentLoadTime tidigare frågor läggs på, men lägre eftersom WriteOutputTime vi bara projicerar en egenskap. |
SELECT TOP 500 udf.toPercent(c.N) FROM c |
"UserDefinedFunctionExecutionTime": "00:00:00.2136500" |
Cirka 213 ms används för UserDefinedFunctionExecutionTime att köra UDF på varje värde i c.N . |
SELECT TOP 500 c.Name FROM c WHERE STARTSWITH(c.Name, 'Den') |
"IndexLookupTime": "00:00:00.0006400", "SystemFunctionExecutionTime": "00:00:00.0074100" |
Cirka 0,6 ms spenderas IndexLookupTime på /Name/? . Merparten av frågekörningstiden (~7 ms) i SystemFunctionExecutionTime . |
SELECT TOP 500 c.Name FROM c WHERE STARTSWITH(LOWER(c.Name), 'den') |
"IndexLookupTime": "00:00:00", "RetrievedDocumentCount": 2491, "OutputDocumentCount": 500 |
Frågan utförs som en genomsökning eftersom den använder LOWER och 500 av 2 491 hämtade dokument returneras. |
Nästa steg
- Mer information om vilka frågeoperatorer SQL och nyckelord som stöds finns i SQL fråga.
- Mer information om enheter för begäran finns i enheter för begäran.
- Mer information om indexeringsprincip finns i Indexeringsprincip