Tipps zur Abfrageleistung für Azure Cosmos DB-SDKs

GILT FÜR: NoSQL

Azure Cosmos DB ist eine schnelle und flexible verteilte Datenbank mit nahtloser Skalierung, garantierter Latenz und garantiertem Durchsatz. Die Skalierung Ihrer Datenbank mit Azure Cosmos DB erfordert weder aufwendige Änderungen an der Architektur noch das Schreiben von komplexem Code. Zentrales Hoch- und Herunterskalieren ist ebenso problemlos möglich wie ein einzelner API-Aufruf. Weitere Informationen finden Sie unter Bereitstellen von Standarddurchsatz (manuell) für einen Azure Cosmos-Container und Bereitstellen von Standarddurchsatz (manuell) für eine Datenbank in Azure Cosmos DB.

Reduzieren von Abfrageplanaufrufen

Zum Ausführen einer Abfrage muss ein Abfrageplan erstellt werden. Dies stellt im Allgemeinen eine Netzwerkanforderung an das Azure Cosmos DB-Gateway dar, wodurch die Latenz des Abfragevorgangs erhöht wird. Es gibt zwei Möglichkeiten, diese Anforderung zu entfernen und die Latenz des Abfragevorgangs zu reduzieren:

Optimieren einzelner Partitionsabfragen mit Optimistic Direct Execution

Azure Cosmos DB NoSQL verfügt über eine Optimierung mit dem Namen „Optimistic Direct Execution (ODE)“, die die Effizienz bestimmter NoSQL-Abfragen verbessern kann. Insbesondere Abfragen, die keine Verteilung erfordern, umfassen diejenigen, die auf einer einzelnen physischen Partition ausgeführt werden können oder über Antworten verfügen, die keine Paginierung erfordern. Abfragen, die keine Verteilung erfordern, können einige Prozesse überspringen, z. B. die clientseitige Abfrageplangenerierung und das Neuschreiben von Abfragen, wodurch die Abfragelatenz und die RU-Kosten reduziert werden. Wenn Sie den Partitionsschlüssel in der Anforderung oder Abfrage selbst angeben (oder nur über eine physische Partition verfügen), und die Ergebnisse Ihrer Abfrage keine Paginierung erfordern, kann die ODE Ihre Abfragen verbessern.

Hinweis

Optimistic Direct Execution (ODE), die eine verbesserte Leistung für Abfragen bietet, die keine Verteilung erfordern, sollten nicht mit Direct Mode verwechselt werden, was ein Pfad zum Verbinden Ihrer Anwendung mit Back-End-Replikaten ist.

ODE ist jetzt verfügbar und standardmäßig im .NET-SDK (Vorschau) für Versionen 3.38.0 und höher aktiviert. Wenn Sie eine Abfrage ausführen und einen Partitionsschlüssel in der Anforderung oder Abfrage selbst angeben oder Ihre Datenbank nur über eine physische Partition verfügt, kann Ihre Abfrageausführung die Vorteile der ODE nutzen. Um ODE zu deaktivieren, legen Sie EnableOptimisticDirectExecution in QueryRequestOptions auf FALSCH fest.

Einzelpartitionsabfragen mit GROUP BY-, ORDER BY-, DISTINCT- und Aggregationsfunktionen (wie Summe, Mittel, Min und Max) können von der Verwendung der ODE erheblich profitieren. In Szenarien, in denen die Abfrage jedoch auf mehrere Partitionen abzielt oder weiterhin eine Paginierung erfordert, können die Latenz der Abfrageantwort und die RU-Kosten höher sein als ohne die ODE. Daher empfehlen wir bei der Verwendung der ODE Folgendes:

  • Geben Sie den Partitionsschlüssel im Aufruf oder in der Abfrage selbst an.
  • Stellen Sie sicher, dass ihre Datengröße nicht zunimmt und die Partition aufgeteilt wurde.
  • Stellen Sie sicher, dass Ihre Abfrageergebnisse keine Paginierung erfordern, um die Vorteile der ODE in vollem Umfang zu nutzen.

Im Folgenden finden Sie einige Beispiele für einfache Abfragen mit einer einzelnen Partition, die von der ODE profitieren können:

- SELECT * FROM r
- SELECT * FROM r WHERE r.pk == "value"
- SELECT * FROM r WHERE r.id > 5
- SELECT r.id FROM r JOIN id IN r.id
- SELECT TOP 5 r.id FROM r ORDER BY r.id
- SELECT * FROM r WHERE r.id > 5 OFFSET 5 LIMIT 3 

Es kann Fälle geben, in denen Abfragen mit einer einzelnen Partition weiterhin eine Verteilung erfordern, wenn die Anzahl der Datenelemente im Laufe der Zeit zunimmt und Ihre Azure Cosmos DB-Datenbank die Partition aufteilt. Beispiele für Abfragen, bei denen dies auftreten könnte:

- SELECT Count(r.id) AS count_a FROM r
- SELECT DISTINCT r.id FROM r
- SELECT Max(r.a) as min_a FROM r
- SELECT Avg(r.a) as min_a FROM r
- SELECT Sum(r.a) as sum_a FROM r WHERE r.a > 0 

Einige komplexe Abfragen können immer eine Verteilung erfordern, auch wenn sie auf eine einzelne Partition ausgerichtet sind. Beispiele für einfache Abfragen sind:

- SELECT Sum(id) as sum_id FROM r JOIN id IN r.id
- SELECT DISTINCT r.id FROM r GROUP BY r.id
- SELECT DISTINCT r.id, Sum(r.id) as sum_a FROM r GROUP BY r.id
- SELECT Count(1) FROM (SELECT DISTINCT r.id FROM root r)
- SELECT Avg(1) AS avg FROM root r 

Es ist wichtig zu beachten, dass die ODE möglicherweise nicht immer den Abfrageplan abruft und infolgedessen nicht in der Lage ist, nicht unterstützte Abfragen nicht zuzulassen oder zu deaktivieren. Beispielsweise sind solche Abfragen nach der Partitionsaufteilung nicht mehr für die ODE geeignet und werden daher nicht ausgeführt, da die clientseitige Abfrageplanauswertung diese blockiert. Um Kompatibilitäts-/Dienstkontinuität zu gewährleisten, ist es wichtig sicherzustellen, dass nur Abfragen mit der ODE verwendet werden, die in Szenarien ohne die ODE vollständig unterstützt werden (d. h. sie werden ausgeführt und erzeugen das richtige Ergebnis im allgemeinen Fall mit mehreren Partitionen).

Hinweis

Die Verwendung von ODE kann dazu führen, dass ein neuer Typ von Fortsetzungstoken generiert wird. Ein solches Token wird von den älteren SDKs entwurfsbedingt nicht erkannt, und dies könnte zu einer Ausnahme „Fehlerhaftes Fortsetzungstoken“ führen. Wenn Sie ein Szenario haben, in dem Token, die aus den neueren SDKs generiert wurden, von einem älteren SDK verwendet werden, empfehlen wir einen 2-Schritt-Ansatz für das Upgrade:

  • Führen Sie ein Upgrade auf das neue SDK durch und deaktivieren Sie ODE, beides zusammen als Teil einer einzelnen Bereitstellung. Warten Sie, bis alle Knoten ein Upgrade durchführen.
    • Um ODE zu deaktivieren, legen Sie EnableOptimisticDirectExecution in QueryRequestOptions auf FALSCH fest.
  • Aktivieren Sie ODE als Teil der zweiten Bereitstellung für alle Knoten.

Nutzung der lokalen Abfrageplangenerierung

Das SQL SDK enthält die native Datei „ServiceInterop.dll“, um Abfragen lokal zu analysieren und zu optimieren. „ServiceInterop.dll“ wird nur auf der Windows x64-Plattform unterstützt. Bei den folgenden Anwendungstypen wird standardmäßig die 32-Bit-Hostverarbeitung verwendet. Um die Hostverarbeitung auf die 64-Bit-Verarbeitung umzustellen, führen Sie je nach Typ Ihrer Anwendung die folgenden Schritte aus:

  • Bei ausführbaren Anwendungen können Sie die Host-Verarbeitung ändern, indem Sie das Plattformziel im Fenster Projekteigenschaften auf der Registerkarte Erstellen auf x64 setzen.

  • Bei VSTest-basierten Testprojekten können Sie die Hostverarbeitung ändern, indem Sie in der Menüoption Visual Studio Test die Option Test>Testeinstellungen>Default Processor Architecture as X64 (Standardprozessorarchitektur als x64) auswählen.

  • Bei lokal bereitgestellten ASP.NET-Webanwendungen ändern Sie die Hostverarbeitung, indem Sie unter Extras>Optionen>Projekte und Projektmappen>Webprojekte die Option 64-Bit-Version von IIS Express für Websites und Projekte verwenden aktivieren.

  • Für ASP.NET-Webanwendungen, die in Azure bereitgestellt werden, können Sie die Hostverarbeitung ändern, indem Sie im Azure-Portal unter Anwendungseinstellungen die 64-Bit-Plattform auswählen.

Hinweis

Standardmäßig ist bei neuen Visual Studio-Projekten Beliebige CPU festgelegt. Es wird empfohlen, Ihr Projekt auf x64 festzulegen, damit es nicht zu x86 wechselt. Ein Projekt mit der Einstellung Beliebige CPU kann schnell zu x86 wechseln, wenn eine Abhängigkeit hinzugefügt wird, die nur bei x86 verfügbar ist.
Die Datei „ServiceInterop.dll“ muss sich im selben Ordner befinden, aus dem die SDK-DLL ausgeführt wird. Dies sollte nur dann von Bedeutung sein, wenn Sie DLLs manuell kopieren oder über benutzerdefinierte Build-/Bereitstellungssysteme verfügen.

Verwenden von Abfragen mit nur einer Partition

Für Abfragen, die auf einen Partitionsschlüssel abzielen, indem sie die PartitionKey-Eigenschaft in QueryRequestOptions festlegen und keine Aggregationen enthalten (einschließlich Distinct, DCount, Group By). In diesem Beispiel wird das Partitionsschlüsselfeld von /state nach dem Wert Washington gefiltert.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle' AND c.state = 'Washington'"
{
    // ...
}

Optional können Sie den Partitionsschlüssel als Teil des Anforderungsoptionenobjekts bereitstellen.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Washington")}))
{
    // ...
}

Hinweis

Für partitionsübergreifende Abfragen muss das SDK alle vorhandenen Partitionen besuchen, um nach Ergebnissen zu suchen. Je mehr physische Partitionen der Container hat, desto langsamer sind sie tendenziell.

Vermeiden der unnötigen Neuerstellung des Iterators

Wenn alle Abfrageergebnisse von der aktuellen Komponente genutzt werden, müssen Sie den Iterator nicht mit der Fortsetzung für jede Seite neu erstellen. Ziehen Sie es immer vor, die Abfrage vollständig zu leeren, es sei denn, die Paginierung wird von einer anderen aufrufenden Komponente gesteuert:

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Washington")}))
{
    while (feedIterator.HasMoreResults) 
    {
        foreach(MyItem document in await feedIterator.ReadNextAsync())
        {
            // Iterate through documents
        }
    }
}

Optimieren des Parallelitätsgrades

Optimieren Sie bei Abfragen die Eigenschaft MaxConcurrency in QueryRequestOptions, um die besten Konfigurationen für Ihre Anwendung zu ermitteln, insbesondere, wenn Sie partitionsübergreifende Abfragen (ohne Filter für den Partitionsschlüsselwert) ausführen. MaxConcurrency steuert die maximale Anzahl von parallelen Aufgaben, d. h. das Maximum von Partitionen, die parallel besucht werden. Wenn Sie den Wert auf -1 festlegen, kann das SDK die optimale Parallelität automatisch festlegen.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { 
        PartitionKey = new PartitionKey("Washington"),
        MaxConcurrency = -1 }))
{
    // ...
}

Annahme:

  • D = Standardwert, maximale Anzahl paralleler Aufgaben (= Gesamtzahl der Prozessoren auf dem Clientcomputer)
  • P = Vom Benutzer angegebene maximale Anzahl paralleler Aufgaben
  • N = Anzahl der Partitionen, auf die zur Beantwortung einer Abfrage zugegriffen werden muss

Es folgen die Auswirkungen auf das Verhalten der parallelen Abfragen bei unterschiedlichen Werten für P.

  • (P == 0) => serieller Modus
  • (P == 1) => maximal eine Aufgabe
  • (P > 1) => minimale Anzahl (P, N) paralleler Aufgaben
  • (P < 1) => minimale Anzahl (N, D) paralleler Aufgaben

Optimieren der Seitengröße

Wenn Sie eine SQL-Abfrage stellen, werden die Ergebnisse bei einem zu großen Resultset segmentiert zurückgegeben.

Hinweis

Die MaxItemCount-Eigenschaft sollte nicht nur für die Paginierung verwendet werden. Ihr Hauptverwendungszweck ist die Verbesserung der Leistung von Abfragen durch Reduzierung der maximalen Anzahl von Elementen, die auf einer einzigen Seite zurückgegeben werden.

Sie können die Seitengröße auch mithilfe der verfügbaren Azure Cosmos DB-SDKs festlegen. Mit der MaxItemCount-Eigenschaft in QueryRequestOptions können Sie die maximale Anzahl von Elementen festlegen, die beim Enumerationsvorgang zurückgegeben werden. Wenn MaxItemCount auf „-1“ festgelegt ist, ermittelt das SDK automatisch den optimalen Wert abhängig von der Größe des Dokuments. Beispiel:

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { 
        PartitionKey = new PartitionKey("Washington"),
        MaxItemCount = 1000}))
{
    // ...
}

Beim Ausführen einer Abfrage werden die resultierenden Daten in einem TCP-Paket gesendet. Wenn Sie einen zu niedrigen Wert für MaxItemCount angeben, ist die zum Senden der Daten im TCP-Paket erforderliche Anzahl der Roundtrips hoch, was sich auf die Leistung auswirkt. Wenn Sie nicht sicher sind, welchen Wert Sie für die MaxItemCount-Eigenschaft festlegen sollen, empfiehlt es sich, den Wert auf „-1“ festzulegen und den Standardwert vom SDK auswählen zu lassen.

Die Puffergröße optimieren

Parallele Abfragen sind so konzipiert, dass Ergebnisse vorab abgerufen werden, während der Client den aktuellen Batch der Ergebnisse verarbeitet. Dieser Vorababruf führt zu einer Verbesserung der allgemeinen Latenz einer Abfrage. Durch die Eigenschaft MaxBufferedItemCount in QueryRequestOptions wird die Anzahl von vorab abgerufenen Ergebnissen begrenzt. Wenn Sie MaxBufferedItemCount auf die erwartete Anzahl von zurückgegebenen Ergebnissen (oder eine höhere Zahl) festlegen, ist der Vorteil durch das vorherige Abrufen für die Abfrage am größten. Wenn Sie diesen Wert auf „-1“ festlegen, kann das System die Anzahl der zu puffernden Elemente automatisch festlegen.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { 
        PartitionKey = new PartitionKey("Washington"),
        MaxBufferedItemCount = -1}))
{
    // ...
}

Das vorherige Abrufen funktioniert unabhängig vom Parallelitätsgrad, und es ist nur ein Puffer für die Daten aller Partitionen vorhanden.

Nächste Schritte

Weitere Informationen über Leistung mit dem .NET SDK:

Reduzieren von Abfrageplanaufrufen

Zum Ausführen einer Abfrage muss ein Abfrageplan erstellt werden. Dies stellt im Allgemeinen eine Netzwerkanforderung an das Azure Cosmos DB-Gateway dar, wodurch die Latenz des Abfragevorgangs erhöht wird.

Zwischenspeichern von Abfrageplänen

Der Abfrageplan für eine Abfrage, die auf eine einzelne Partition abzielt, wird auf dem Client zwischengespeichert. Dadurch entfällt nach dem ersten Aufruf die Notwendigkeit, das Gateway abzufragen, um den Abfrageplan abzurufen. Der Schlüssel für den zwischengespeicherten Abfrageplan ist die SQL-Abfragezeichenfolge. Sie müssen sicherstellen, dass Ihre Abfrage parametrisiert ist. Wenn dies nicht der Fall ist, resultiert die Cachesuche des Abfrageplans häufig in einem Cachefehler, da es unwahrscheinlich ist, dass die Abfragezeichenfolge der einzelnen Aufrufe identisch ist. Das Zwischenspeichern von Abfrageplänen ist standardmäßig für Java SDK ab Version 4.20.0 sowie für Spring Data Azure Cosmos DB SDK ab Version 3.13.0 aktiviert.

Verwenden parametrisierter Abfragen für eine einzelne Partition

Bei parametrisierten Abfragen, die mit setPartitionKey in CosmosQueryRequestOptions auf einen Partitionsschlüssel festgelegt sind und keine Aggregationen enthalten (einschließlich Distinct, DCount, Group By), kann der Abfrageplan vermieden werden:

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey("Washington"));

ArrayList<SqlParameter> paramList = new ArrayList<SqlParameter>();
paramList.add(new SqlParameter("@city", "Seattle"));
SqlQuerySpec querySpec = new SqlQuerySpec(
        "SELECT * FROM c WHERE c.city = @city",
        paramList);

//  Sync API
CosmosPagedIterable<MyItem> filteredItems = 
    container.queryItems(querySpec, options, MyItem.class);

//  Async API
CosmosPagedFlux<MyItem> filteredItems = 
    asyncContainer.queryItems(querySpec, options, MyItem.class);

Hinweis

Für partitionsübergreifende Abfragen muss das SDK alle vorhandenen Partitionen besuchen, um nach Ergebnissen zu suchen. Je mehr physische Partitionen der Container hat, desto langsamer sind sie tendenziell.

Optimieren des Parallelitätsgrades

Bei parallelen Abfragen werden mehrere Partitionen parallel abgefragt. Die Daten eines individuell partitionierten Containers werden in Bezug auf die Abfrage aber seriell abgerufen. Verwenden Sie also setMaxDegreeOfParallelism in CosmosQueryRequestOptions, um den Wert auf die Anzahl der Partitionen festzulegen, über die Sie verfügen. Falls Ihnen die Anzahl von Partitionen nicht bekannt ist, können Sie setMaxDegreeOfParallelism auf einen hohen Wert festlegen. Das System wählt für den maximalen Grad an Parallelität dann den minimalen Wert aus (Anzahl von Partitionen, Benutzereingabe). Wenn Sie den Wert auf -1 festlegen, kann das SDK die optimale Parallelität automatisch festlegen.

Es ist wichtig zu beachten, dass sich für parallele Abfragen die größten Vorteile ergeben, wenn die Daten in Bezug auf die Abfrage gleichmäßig auf alle Partitionen verteilt werden. Wenn der partitionierte Container so partitioniert ist, dass sich alle Daten bzw. die meisten Daten, die von einer Abfrage zurückgegeben werden, auf einigen wenigen Partitionen befinden (schlimmstenfalls nur auf einer Partition), kann dies die Leistung beeinträchtigen.

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey("Washington"));
options.setMaxDegreeOfParallelism(-1);

// Define the query

//  Sync API
CosmosPagedIterable<MyItem> filteredItems = 
    container.queryItems(querySpec, options, MyItem.class);

//  Async API
CosmosPagedFlux<MyItem> filteredItems = 
    asyncContainer.queryItems(querySpec, options, MyItem.class);

Annahme:

  • D = Standardwert, maximale Anzahl paralleler Aufgaben (= Gesamtzahl der Prozessoren auf dem Clientcomputer)
  • P = Vom Benutzer angegebene maximale Anzahl paralleler Aufgaben
  • N = Anzahl der Partitionen, auf die zur Beantwortung einer Abfrage zugegriffen werden muss

Es folgen die Auswirkungen auf das Verhalten der parallelen Abfragen bei unterschiedlichen Werten für P.

  • (P == 0) => serieller Modus
  • (P == 1) => maximal eine Aufgabe
  • (P > 1) => minimale Anzahl (P, N) paralleler Aufgaben
  • (P == -1) => minimale Anzahl (N, D) paralleler Aufgaben

Optimieren der Seitengröße

Wenn Sie eine SQL-Abfrage stellen, werden die Ergebnisse bei einem zu großen Resultset segmentiert zurückgegeben. Ergebnisse werden standardmäßig in Blöcken mit je 100 Elementen oder 4 MB zurückgegeben (je nachdem, welcher Grenzwert zuerst erreicht wird). Das Erhöhen der Seitengröße reduziert die Anzahl der erforderlichen Roundtrips und steigert die Leistung für Abfragen, die mehr als 100 Elemente zurückgeben. Wenn Sie nicht sicher sind, welcher Wert festgelegt werden soll, ist 1.000 in der Regel eine gute Wahl. Der Arbeitsspeicherverbrauch steigt, wenn die Seitengröße zunimmt. Wenn Ihre Workload sehr viel Arbeitsspeicher benötigt, sollten Sie also einen niedrigeren Wert in Betracht ziehen.

Sie können den Parameter pageSize in iterableByPage() für die synchrone API und byPage() für die asynchrone API verwenden, um eine Seitengröße zu definieren:

//  Sync API
Iterable<FeedResponse<MyItem>> filteredItemsAsPages =
    container.queryItems(querySpec, options, MyItem.class).iterableByPage(continuationToken,pageSize);

for (FeedResponse<MyItem> page : filteredItemsAsPages) {
    for (MyItem item : page.getResults()) {
        //...
    }
}

//  Async API
Flux<FeedResponse<MyItem>> filteredItemsAsPages =
    asyncContainer.queryItems(querySpec, options, MyItem.class).byPage(continuationToken,pageSize);

filteredItemsAsPages.map(page -> {
    for (MyItem item : page.getResults()) {
        //...
    }
}).subscribe();

Die Puffergröße optimieren

Parallele Abfragen sind so konzipiert, dass Ergebnisse vorab abgerufen werden, während der Client den aktuellen Batch der Ergebnisse verarbeitet. Diese Art des Abrufs führt zu einer Verbesserung der Latenz einer Abfrage. setMaxBufferedItemCount in CosmosQueryRequestOptions begrenzt die Anzahl vorab abgerufener Ergebnisse. Um die Vorababrufe zu maximieren, legen Sie die maxBufferedItemCount auf eine höhere Zahl als pageSize fest (HINWEIS: Dies kann auch zu einer hohen Arbeitsspeichernutzung führen). Um das Vorababrufen zu minimieren, legen Sie die maxBufferedItemCount gleich der pageSize fest. Wenn Sie diesen Wert auf „0“ festlegen, kann das System die Anzahl der zu puffernden Elemente automatisch festlegen.

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey("Washington"));
options.setMaxBufferedItemCount(-1);

// Define the query

//  Sync API
CosmosPagedIterable<MyItem> filteredItems = 
    container.queryItems(querySpec, options, MyItem.class);

//  Async API
CosmosPagedFlux<MyItem> filteredItems = 
    asyncContainer.queryItems(querySpec, options, MyItem.class);

Das vorherige Abrufen funktioniert unabhängig vom Parallelitätsgrad, und es ist nur ein Puffer für die Daten aller Partitionen vorhanden.

Nächste Schritte

Weitere Informationen über Leistung mit dem Java-SDK:

Reduzieren von Abfrageplanaufrufen

Zum Ausführen einer Abfrage muss ein Abfrageplan erstellt werden. Dies stellt im Allgemeinen eine Netzwerkanforderung an das Azure Cosmos DB-Gateway dar, wodurch die Latenz des Abfragevorgangs erhöht wird. Es gibt eine Möglichkeit, diese Anforderung zu entfernen und die Latenz des Abfragevorgangs für einzelne Partitionen zu verringern. Geben Sie für Einzelpartitionsabfragen den Partitionsschlüsselwert für das Element an, und übergeben Sie ihn als partition_key-Argument:

items = container.query_items(
        query="SELECT * FROM r where r.city = 'Seattle'",
        partition_key="Washington"
    )

Optimieren der Seitengröße

Wenn Sie eine SQL-Abfrage stellen, werden die Ergebnisse bei einem zu großen Resultset segmentiert zurückgegeben. Mit max_item_count können Sie die maximale Anzahl von Elementen festlegen, die beim Enumerationsvorgang zurückgegeben werden.

items = container.query_items(
        query="SELECT * FROM r where r.city = 'Seattle'",
        partition_key="Washington",
        max_item_count=1000
    )

Nächste Schritte

Weitere Informationen zur Verwendung des Python SDK für die API für NoSQL finden Sie hier:

Reduzieren von Abfrageplanaufrufen

Zum Ausführen einer Abfrage muss ein Abfrageplan erstellt werden. Dies stellt im Allgemeinen eine Netzwerkanforderung an das Azure Cosmos DB-Gateway dar, wodurch die Latenz des Abfragevorgangs erhöht wird. Es gibt eine Möglichkeit, diese Anforderung zu entfernen und die Latenz des Abfragevorgangs für einzelne Partitionen zu verringern. Für Einzelpartitionsabfragen gibt es zwei Möglichkeiten, die Abfrage auf eine einzelne Partition zu beschränken.

Verwenden Sie einen parametrisierten Abfrageausdruck, und geben Sie den Partitionsschlüssels in der Abfrageanweisung an. Die Abfrage wird programmgesteuert als SELECT * FROM todo t WHERE t.partitionKey = 'Bikes, Touring Bikes' zusammengesetzt:

// find all items with same categoryId (partitionKey)
const querySpec = {
    query: "select * from products p where p.categoryId=@categoryId",
    parameters: [
        {
            name: "@categoryId",
            value: "Bikes, Touring Bikes"
        }
    ]
};

// Get items 
const { resources } = await container.items.query(querySpec).fetchAll();

for (const item of resources) {
    console.log(`${item.id}: ${item.name}, ${item.sku}`);
}

Alternativ dazu geben Sie partitionKey in FeedOptions ein, und übergeben Sie es als Argument:

const querySpec = {
    query: "select * from products p"
};

const { resources } = await container.items.query(querySpec, { partitionKey: "Bikes, Touring Bikes" }).fetchAll();

for (const item of resources) {
    console.log(`${item.id}: ${item.name}, ${item.sku}`);
}

Optimieren der Seitengröße

Wenn Sie eine SQL-Abfrage stellen, werden die Ergebnisse bei einem zu großen Resultset segmentiert zurückgegeben. Mit maxItemCount können Sie die maximale Anzahl von Elementen festlegen, die beim Enumerationsvorgang zurückgegeben werden.

const querySpec = {
    query: "select * from products p where p.categoryId=@categoryId",
    parameters: [
        {
            name: "@categoryId",
            value: items[2].categoryId
        }
    ]
};

const { resources } = await container.items.query(querySpec, { maxItemCount: 1000 }).fetchAll();

for (const item of resources) {
    console.log(`${item.id}: ${item.name}, ${item.sku}`);
}

Nächste Schritte

Weitere Informationen zur Verwendung des Node.js SDK für die API für NoSQL finden Sie hier: