Freigeben über


Indizierungsrichtlinien in Azure Cosmos DB

GILT FÜR: NoSQL

In Azure Cosmos DB verfügt jeder Container über eine Indizierungsrichtlinie, die bestimmt, wie die Elemente eines Containers indiziert werden. Die standardmäßige Indizierungsrichtlinie für neu erstellte Container indiziert sämtliche Eigenschaften jedes Elements und erzwingt Bereichsindizes für jede Zeichenfolge oder Zahl. Dadurch erzielen Sie eine gute Abfrageleistung, ohne sich im Vorfeld Gedanken über die Indizierung und Indexverwaltung machen zu müssen.

In einigen Fällen ist eventuell sinnvoll, dieses automatische Verhalten zu übersteuern, damit es besser für Ihre Anforderungen passt. Sie können die Indizierungsrichtlinie eines Containers anpassen, indem Sie seinen Indizierungsmodus festlegen und Eigenschaftenpfade ein- oder ausschließen.

Hinweis

Die in diesem Artikel beschriebene Methode zur Aktualisierung von Indizierungsrichtlinien gilt nur für die API für NoSQL von Azure Cosmos DB. Informationen zur Indizierung finden Sie unter Azure Cosmos DB-API für MongoDB.

Indizierungsmodus

Azure Cosmos DB unterstützt zwei Indizierungsmodi:

  • Konsistent: Der Index wird synchron aktualisiert, wenn Sie Elemente erstellen, aktualisieren oder löschen. Damit entspricht die Konsistenz Ihrer Leseabfragen der für das Konto konfigurierten Konsistenz.
  • Keine: Die Indizierung ist für den Container deaktiviert. Dieser Modus wird häufig verwendet, wenn ein Container als reiner Schlüssel-Wert-Speicher verwendet wird, für den keine sekundären Indizes erforderlich sind. Sie kann auch verwendet werden, um die Leistung von Massenvorgängen zu verbessern. Nach Abschluss der Massenvorgänge kann der Indexmodus auf „Konsistent“ festgelegt und dann mit IndexTransformationProgress überwacht werden, bis er abgeschlossen ist.

Hinweis

Azure Cosmos DB unterstützt auch einen verzögerten Indizierungsmodus. Bei der verzögerten Indizierung werden Updates des Indexes mit einer wesentlich niedrigeren Prioritätsstufe ausgeführt, wenn die Engine keine andere Arbeit ausführt. Dies kann zu inkonsistenten oder unvollständigen Abfrageergebnissen führen. Wenn Sie beabsichtigen, einen Azure Cosmos DB-Container abzufragen, sollten Sie nicht die verzögerte Indizierung verwenden. Für neue Container kann keine verzögerte Indizierung ausgewählt werden. Sie können eine Ausnahme beantragen, indem Sie sich an cosmosdbindexing@microsoft.com wenden (sofern Sie kein Azure Cosmos DB-Konto im serverlosen Modus verwenden, der keine verzögerte Indizierung unterstützt).

Diese Indizierungsrichtlinie ist standardmäßig auf automatic festgelegt. Hierzu wird die automatic-Eigenschaft der Indizierungsrichtlinie auf true festgelegt. Wenn diese Eigenschaft auf true festgelegt wird, kann Azure Cosmos DB Elemente beim Schreiben automatisch indizieren.

Indexgröße

In Azure Cosmos DB ist die Summe des Speicherverbrauchs die Kombination von Datengröße und Indexgröße. Im Folgenden sind einige Merkmale der Indexgröße aufgeführt:

  • Die Indexgröße hängt von der Indizierungsrichtlinie ab. Wenn alle Eigenschaften indiziert werden, kann der Index größer als die Daten sein.
  • Wenn die Daten gelöscht werden, werden die Indizes nahezu fortlaufend komprimiert. Bei kleinen Datenlöschungen erkennen Sie jedoch möglicherweise nicht sofort eine Verringerung der Indexgröße.
  • Die Indexgröße kann sich vorübergehend erhöhen, wenn physische Partitionen aufgeteilt werden. Der Speicherplatz für den Index wird nach Abschluss der Partitionsaufteilung wieder freigegeben.

Ein- und Ausschließen von Eigenschaftenpfaden

Mit einer benutzerdefinierten Indizierungsrichtlinie können Eigenschaftenpfade angegeben werden, die explizit in die Indizierung eingeschlossen oder von ihr ausgeschlossen werden. Indem Sie die Anzahl der indizierten Pfade optimieren, können Sie die Wartezeit und die RU-Gebühr für Schreibvorgänge erheblich verringern. Diese Pfade werden anhand der Methode, die im Übersichtsabschnitt zur Indizierung beschrieben wird, definiert. Dabei gelten die folgenden Ergänzungen:

  • Ein Pfad zu einem Skalarwert (Zeichenfolge oder Zahl) endet auf /?.
  • Elemente aus einem Array werden über die /[]-Notation (anstelle von /0, /1 usw.) adressiert.
  • Der Platzhalter /* kann verwendet werden, um alle Elemente unter einem Knoten einzufügen.

Betrachten wir dasselbe Beispiel erneut:

    {
        "locations": [
            { "country": "Germany", "city": "Berlin" },
            { "country": "France", "city": "Paris" }
        ],
        "headquarters": { "country": "Belgium", "employees": 250 },
        "exports": [
            { "city": "Moscow" },
            { "city": "Athens" }
        ]
    }
  • Der employees-Pfad von headquarters lautet /headquarters/employees/?.

  • Der country-Pfad von locations lautet /locations/[]/country/?.

  • Der Pfad zu allen Elementen unter headquarters lautet /headquarters/*.

Wir könnten beispielsweise den Pfad /headquarters/employees/? einschließen. Dadurch könnten wir sicherstellen, dass die Eigenschaft employees indiziert wird, aber kein zusätzlicher geschachtelter JSON innerhalb dieser Eigenschaft.

Strategie für das Ein- und Ausschließen

Jede Indizierungsrichtlinie muss den Stammpfad /* entweder als eingeschlossenen oder als ausgeschlossenen Pfad enthalten.

  • Schließen Sie den Stammpfad ein, um einzelne Pfade auszuschließen, die nicht indiziert werden müssen. Diese Vorgehensweise wird empfohlen, da dabei Azure Cosmos DB proaktiv jede neue Eigenschaft indiziert, die dem Modell hinzugefügt wird.

  • Schließen Sie den Stammpfad aus, um einzelne Pfade einzuschließen, die indiziert werden müssen. Der Pfad der Partitionsschlüsseleigenschaft wird standardmäßig nicht mit der ausschließenden Strategie indiziert und sollte bei Bedarf explizit eingeschlossen werden.

  • Für Pfade mit regulären Zeichen, die alphanumerische Zeichen und Unterstriche (_) enthalten, müssen Sie die Pfadzeichenkette nicht mit doppelten Anführungszeichen als Escapezeichen umgeben (z.B. "/Pfad/?"). Für Pfade mit anderen Sonderzeichen müssen Sie die Pfadzeichenkette mit doppelten Anführungszeichen als Escapezeichen umgeben (z.B. "/"Pfad-abc"/?"). Wenn Sie Sonderzeichen in Ihrem Pfad erwarten, können Sie aus Sicherheitsgründen jeden Pfad mit Escapezeichen umgeben. Funktionell macht es keinen Unterschied, ob Sie jeden Pfad mit Escapezeichen umgeben oder nur diejenigen mit Sonderzeichen.

  • Die Systemeigenschaft _etag wird von der Indizierung standardmäßig ausgeschlossen, sofern sie nicht zum für die Indizierung eingeschlossenen Pfad hinzugefügt wird.

  • Wenn der Indizierungsmodus auf Konsistent festgelegt ist, werden die Systemeigenschaften id und _ts automatisch indiziert.

  • Wenn ein explizit indizierter Pfad in einem Element nicht vorhanden ist, wird dem Index ein Wert hinzugefügt, um anzugeben, dass der Pfad nicht definiert ist.

Alle explizit eingeschlossenen Pfade werden Werte haben, die dem Index für jedes Element im Container hinzugefügt werden, selbst wenn der Pfad für ein bestimmtes Element nicht definiert ist.

Exemplarische Indizierungsrichtlinien zum Ein- und Ausschließen von Pfaden finden Sie in diesem Abschnitt.

Vorrang beim Einschließen/Ausschließen

Wenn es bei Ihren eingeschlossenen und ausgeschlossenen Pfaden zu einem Konflikt kommt, hat der genauere Pfad Vorrang.

Hier sehen Sie ein Beispiel:

Eingeschlossener Pfad:/food/ingredients/nutrition/*

Ausgeschlossener Pfad:/food/ingredients/*

In diesem Fall hat der eingeschlossene Pfad Vorrang vor dem ausgeschlossenen Pfad, da er präziser ist. Basierend auf diesen Pfaden würden alle Daten im food/ingredients-Pfad oder Daten, die darin geschachtelt sind, vom Index ausgeschlossen werden. Die Ausnahme wären Daten innerhalb des eingeschlossenen Pfads /food/ingredients/nutrition/*. Diese würden indiziert werden.

Hier finden Sie einige Regeln für den Vorrang bei eingeschlossenen und ausgeschlossenen Pfaden in Azure Cosmos DB:

  • Tiefere Pfade sind präziser als enger gefasste Pfade. Beispielsweise ist /a/b/? präziser als /a/?.

  • /? ist präziser als /*. /a/? ist beispielsweise präziser als /a/*, /a/? hat also Vorrang.

  • Der Pfad /* muss entweder ein eingeschlossener oder ein ausgeschlossener Pfad sein.

Volltextindizes

Hinweis

Sie müssen die Previewfunktion für die Volltext- und Hybridsuche für die NoSQL-API aktivieren, um einen Volltextindex anzugeben.

Volltextindizes ermöglichen die Volltextsuche und eine effiziente Bewertung mithilfe des Index. Sie können ganz einfach einen Volltextpfads in einer Indizierungsrichtlinie definieren, indem Sie einen fullTextIndexes-Abschnitt in die Indizierungsrichtlinie einschließen, der alle zu indizierenden Textpfade enthält. Zum Beispiel:

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/\"_etag\"/?"
        },
    ],
    "fullTextIndexes": [
        {
            "path": "/text"
        }
    ]
}

Wichtig

Eine Volltext-Indizierungsrichtlinie muss sich in dem Pfad befinden, der in der Volltextrichtlinie des Containers definiert ist. Weitere Informationen zu Vektorrichtlinien für Container.

Vektorindizes

Hinweis

Sie müssen das Azure Cosmos DB-Feature für die NoSQL-Vektorsuche aktivieren, um einen Vektorindex anzugeben.

Vektorindizes erhöhen die Effizienz beim Ausführen von Vektorsuchen mithilfe der VectorDistance-Systemfunktion. Vektorsuchen haben geringere Wartezeit, einen höheren Durchsatz und weniger RU-Verbrauch bei Verwendung eines Vektorindexes. Sie können die folgenden Typen von Vektorindexrichtlinien angeben:

Typ Beschreibung Max. Abmessungen
flat Speichert Vektoren im selben Index wie andere indizierte Eigenschaften. 505
quantizedFlat Quantisiert (komprimiert) Vektoren vor dem Speichern im Index. Dies kann die Latenz und den Durchsatz auf Kosten einer geringeren Genauigkeit verbessern. 4096
diskANN Erstellt einen Index basierend auf DiskANN für schnelle und effiziente Näherungssuche. 4096

Wichtig

Derzeit sind Vektorrichtlinien und Vektorindizes nach der Erstellung unveränderlich. Um Änderungen vorzunehmen, erstellen Sie eine neue Sammlung.

Einige Punkte sind zu beachten:

  • Die Indextypen flat und quantizedFlat Indextypen verwenden den Index von Azure Cosmos DB, um jeden Vektor zu speichern und zu lesen, wenn eine Vektorsuche ausgeführt wird. Vektorsuchen mit einem flat Index sind Brute-Force-Suchvorgänge und erzeugen 100 % Genauigkeit oder Rückruf. Das heißt, es ist garantiert, die ähnlichsten Vektoren im Dataset zu finden. Es gibt jedoch eine Einschränkung der 505 Dimensionen für Vektoren in einem flachen Index.

    • Der quantizedFlat Index speichert quantisierte (komprimierte) Vektoren im Index. Vektorsuchen mit quantizedFlat Index sind auch Brute-Force-Suchvorgänge, ihre Genauigkeit kann jedoch etwas kleiner als 100 % sein, da die Vektoren vor dem Hinzufügen zum Index quantisiert werden. Vektorsuchen mit quantized flat sollten jedoch eine geringere Latenz, einen höheren Durchsatz und niedrigere RU-Kosten als Vektorsuchen in einem flat-Index aufweisen. Dies ist eine gute Option für Szenarien, in denen Sie Abfragefilter verwenden, um die Vektorsuche auf einen relativ kleinen Satz von Vektoren einzugrenzen, und eine hohe Genauigkeit ist erforderlich.

    • Der Index diskANN ist ein separater Index, der speziell für Vektoren mit DiskANN definiert ist, einer Suite von Hochleistungsvektorindizierungsalgorithmen, die von Microsoft Research entwickelt wurden. DiskANN-Indizes können einige der niedrigsten Latenz, den höchsten Durchsatz und die niedrigsten RU-Kostenabfragen bieten und gleichzeitig eine hohe Genauigkeit beibehalten. Da DiskANN jedoch ein näherer Nachbarindex (ANN) ist, kann die Genauigkeit niedriger sein als quantizedFlat oder flat.

Die Indizes diskANN und quantizedFlat akzeptieren optionale Indexerstellungsparameter, mit denen Genauigkeit und Latenz ausbalanciert werden können, die für jeden ungefähren nächsten Nachbarn (ANN) im Vektorindex gelten.

  • quantizationByteSize: legt die Größe (in Byte) für die Produktquantisierung fest. Min=1, Standard=dynamic (System entscheidet), Max=512. Das Festlegen eines höheren Werts kann zu einer höheren Genauigkeit bei Vektorsuchen führen, aber mit höheren RU-Kosten und höherer Latenz. Dies gilt für die Indextypen quantizedFlat und DiskANN gleichermaßen.
    • indexingSearchListSize: legt fest, wie viele Vektoren während der Indexerstellung durchsucht werden sollen. Min=10, Standard=100, Max=500. Das Festlegen eines höheren Werts kann zu einer höheren Genauigkeit bei Vektorsuchen führen, aber auch zu einer längeren Indexerstellungszeit und höheren Latenz bei der Vektorerfassung. Dies gilt nur für den Indextyp DiskANN.

Hier ist ein Beispiel für eine Indizierungsrichtlinie mit einem Vektorindex:

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/_etag/?",
        },
        {
            "path": "/vector/*"
        }
    ],
    "vectorIndexes": [
        {
            "path": "/vector",
            "type": "diskANN"
        }
    ]
}

Wichtig

Eine Vektorindizierungsrichtlinie muss sich in dem Pfad befinden, der in der Vektorrichtlinie des Containers definiert ist. Weitere Informationen zu Vektorrichtlinien für Container.

Wichtig

Dieser Vektorpfad wurde dem Abschnitt „excludedPaths“ der Indizierungsrichtlinie hinzugefügt, um eine optimierte Leistung für das Einfügen sicherzustellen. Wenn der Vektorpfad nicht zu „excludedPaths“ hinzugefügt wird, führt dies zu einer höheren RU-Belastung und Latenz für Vektoreinfügungen.

Räumlichkeitsindizes

Wenn Sie in der Indizierungsrichtlinie einen räumlichen Pfad definieren, müssen Sie definieren, welche Art (type) von Index auf diesen Pfad angewendet werden soll. Für räumliche Indizes stehen folgende Arten zur Verfügung:

  • Point

  • Polygon

  • MultiPolygon

  • LineString

Azure Cosmos DB erstellt standardmäßig keine räumlichen Indizes. Wenn Sie integrierte räumliche SQL-Funktionen verwenden möchten, müssen Sie einen räumlichen Index für die erforderlichen Eigenschaften erstellen. Exemplarische Indizierungsrichtlinien zum Hinzufügen räumlicher Indizes finden Sie in diesem Abschnitt.

Tupelindizes

Tupelindizes sind nützlich, wenn Sie nach mehreren Feldern innerhalb eines Arrayelements filtern. Tupelindizes werden im includedPaths-Abschnitt der Indizierungsrichtlinie mithilfe des Tupelbezeichners „[]“ definiert.

Hinweis

Im Gegensatz zu ein- oder ausgeschlossenen Pfaden können Sie keinen Pfad mit dem Platzhalter „/*“ erstellen. Jeder Tupelpfad muss auf „/?“ enden. Wenn ein Tupel in einem Tupelpfad nicht in einem Element vorhanden ist, wird dem Index ein Wert hinzugefügt, um anzugeben, dass das Tupel nicht definiert ist.

Arraytupelpfade werden im includedPaths-Abschnitt unter Verwendung der folgenden Notation definiert.

<path prefix>/[]/{<tuple 1>, <tuple 2> … <tuple n>}/?

Beachten Sie dabei Folgendes:

  • Der erste Teil – das Pfadpräfix – ist der Pfad, der bei den Tupeln gleich ist. Es ist der Pfad vom Stamm zum Array. In diesem Beispiel ist dies „/events“.
  • Darauf folgt der Platzhalterbezeichner „[]“ für das Array. Alle Arraytupelpfade sollten vor dem Tupelbezeichner „{}“ einen Platzhalterbezeichner für das Array enthalten.
  • Als Nächstes wird das Tupel mit dem Tupelbezeichner „{}“ angegeben.
  • Tupel werden durch Kommas getrennt.
  • Das Tuple muss dieselbe Pfadspezifikation wie die anderen Indexpfade aufweisen, wobei einige wenige Ausnahmen gelten:
  • Tupel sollten nicht mit dem führenden Schrägstrich (/) beginnen.
  • Tupel sollten keine Arrayplatzhalter enthalten.
  • Tupel sollten nicht auf ein Fragezeichen (?) oder Sternchen (*) enden.
  • „?” ist das letzte Segment in einem Tupelpfad und sollte unmittelbar nach dem Segment mit dem Tupelbezeichner angegeben werden.

Beispiel:

/events/[]/{name, category}/?

Im Folgenden finden Sie einige Beispiele für gültige Arraytupelpfade:

    “includedPaths”:[  
        {“path”: “/events/[]/{name/first, name/last}/?”}, 
        {“path”: “/events/[]/{name/first, category}/?”}, 
        {“path”: “/events/[]/{name/first, category/subcategory}/?”}, 
        {“path”: “/events/[]/{name/[1]/first, category}/?”}, 
        {“path”: “/events/[]/{[1], [3]}/?”}, 
        {“path”: “/city/[1]/events/[]/{name, category}/?”} 
    ]

Im Folgenden finden Sie einige Beispiele für ungültige Arraytupelpfade:

  • /events/[]/{name/[]/first, category}/?
    • Eines der Tupel enthält einen Arrayplatzhalter.
  • /events/[]/{name, category}/*
    • Das letzte Segment im Arraytupelpfad sollte „?“ sein und nicht „*“.
  • /events/[]/{{name, first},category}/?
    • Der Tupelbezeichner ist geschachtelt.
  • /events/{name, category}/?
    • Der Arrayplatzhalter fehlt vor dem Tupelbezeichner.
  • /events/[]/{/name,/category}/?
    • Das Tupel beginnt mit einem vorangestellten /.
  • /events/[]/{name/?,category/?}/?
    • Das Tupel endet auf ?.
  • /city/[]/events/[]/{name, category}/?
    • Das Pfadpräfix enthält zwei Arrayplatzhalter.

Zusammengesetzte Indizes

Für Abfragen, die eine ORDER BY-Klausel mit zwei oder mehr Eigenschaften besitzen, ist ein zusammengesetzter Index erforderlich. Ein zusammengesetzter Index kann auch definiert werden, um die Leistung vieler Gleichheits- und Bereichsabfragen zu verbessern. Standardmäßig sind keine zusammengesetzten Indizes definiert, weshalb Sie zusammengesetzte Indizes je nach Bedarf hinzufügen müssen.

Im Gegensatz zu eingeschlossenen oder ausgeschlossenen Pfaden können Sie keinen Pfad mit dem /*-Platzhalter erstellen. Jeder zusammengesetzte Pfad muss am Ende des Pfads implizit /? aufweisen, was nicht angegeben werden muss. Zusammengesetzte Pfade führen zu einem Skalarwert, und dieser ist der einzige Wert, der im zusammengesetzten Index eingeschlossen wird. Wenn ein Pfad in einem zusammengesetzten Index in einem Element nicht vorhanden ist oder zu einem nicht skalaren Wert führt, wird dem Index ein Wert hinzugefügt, um anzugeben, dass der Pfad nicht definiert ist.

Beim Definieren eines zusammengesetzten Indexes geben Sie Folgendes an:

  • Zwei oder mehr Eigenschaftspfade. Die Reihenfolge, in der Eigenschaftspfade definiert sind, ist entscheidend.

  • Die Reihenfolge (aufsteigend oder absteigend).

Hinweis

Wenn Sie einen zusammengesetzten Index hinzufügen, werden in der Abfrage vorhandene Bereichsindizes genutzt, bis das Hinzufügen des neuen zusammengesetzten Index abgeschlossen ist. Daher kann es sein, dass beim Hinzufügen eines zusammengesetzten Index nicht sofort Leistungsverbesserungen erkennbar sind. Es ist möglich, den Fortschritt der Indextransformation mit einem der SDKs zu verfolgen.

ORDER BY-Abfragen für mehrere Eigenschaften:

Bei Verwendung zusammengesetzter Indizes für Abfragen, die eine ORDER BY-Klausel mit zwei oder mehr Eigenschaften besitzen, muss Folgendes berücksichtigt werden.

  • Wenn die Pfade des zusammengesetzten Index nicht mit der Reihenfolge der Eigenschaften in der ORDER BY-Klausel übereinstimmen, kann der zusammengesetzte Index die Abfrage nicht unterstützen.

  • Die Reihenfolge der Pfade des zusammengesetzten Index (aufsteigend oder absteigend) muss auch mit der Reihenfolge (order) in der ORDER BY-Klausel übereinstimmen.

  • Der zusammengesetzte Index unterstützt auch eine ORDER BY-Klausel mit umgekehrter Reihenfolge für alle Pfade.

Betrachten Sie das folgende Beispiel, in dem ein zusammengesetzter Index für die Eigenschaften „name“, „age“, und „_ts“ definiert wird:

Zusammengesetzter Index Beispiel einer ORDER BY-Abfrage Unterstützung durch zusammengesetzten Index?
(name ASC, age ASC) SELECT * FROM c ORDER BY c.name ASC, c.age asc Yes
(name ASC, age ASC) SELECT * FROM c ORDER BY c.age ASC, c.name asc No
(name ASC, age ASC) SELECT * FROM c ORDER BY c.name DESC, c.age DESC Yes
(name ASC, age ASC) SELECT * FROM c ORDER BY c.name ASC, c.age DESC No
(name ASC, age ASC, timestamp ASC) SELECT * FROM c ORDER BY c.name ASC, c.age ASC, timestamp ASC Yes
(name ASC, age ASC, timestamp ASC) SELECT * FROM c ORDER BY c.name ASC, c.age ASC No

Sie müssen Ihre Indizierungsrichtlinie anpassen, damit Sie alle notwendigen ORDER BY-Abfragen durchführen können.

Abfragen mit Filtern für mehrere Eigenschaften

Wenn eine Abfrage Filter für zwei oder mehr Eigenschaften enthält, kann es hilfreich sein, einen zusammengesetzten Index für diese Eigenschaften zu erstellen.

Sehen Sie sich beispielsweise die folgende Abfrage an, die sowohl einen Gleichheits- als auch einen Bereichsfilter enthält:

SELECT *
FROM c
WHERE c.name = "John" AND c.age > 18

Diese Abfrage ist effizienter, schneller und beansprucht weniger RUs, wenn sie einen zusammengesetzten Index auf (name ASC, age ASC) anwenden kann.

Abfragen mit mehreren Bereichsfiltern können ebenfalls mit einem zusammengesetzten Index optimiert werden. Ein zusammengesetzter Index kann jedoch immer nur jeweils einen einzelnen Bereichsfilter optimieren. Zu Bereichsfiltern zählen >, <, <=, >= und !=. Der Bereichsfilter muss im zusammengesetzten Index zuletzt definiert werden.

Die folgende Abfrage enthält einen Gleichheits- und zwei Bereichsfilter:

SELECT *
FROM c
WHERE c.name = "John" AND c.age > 18 AND c._ts > 1612212188

Diese Abfrage ist mit einem zusammengesetzten Index auf (name ASC, age ASC) und (name ASC, _ts ASC) effizienter. Die Abfrage würde für (age ASC, name ASC) jedoch keinen zusammengesetzten Index nutzen, da die Eigenschaften mit Gleichheitsfiltern zuerst im zusammengesetzten Index definiert werden müssen. Da ein zusammengesetzter Index immer nur jeweils einen einzelnen Bereichsfilter optimieren kann, werden für (name ASC, age ASC, _ts ASC) anstelle eines einzelnen zusammengesetzten Index zwei separate zusammengesetzte Indizes benötigt.

Bei der Erstellung zusammengesetzter Indizes für Abfragen mit Filtern für mehrere Eigenschaften muss Folgendes berücksichtigt werden:

  • Filterausdrücke können mehrere zusammengesetzte Indizes verwenden.
  • Die Eigenschaften im Filter der Abfrage müssen den Eigenschaften im zusammengesetzten Index entsprechen. Ist eine Eigenschaft im zusammengesetzten Index, aber nicht als Filter in der Abfrage enthalten, wird der zusammengesetzte Index von der Abfrage nicht verwendet.
  • Enthält der Filter einer Abfrage weitere Eigenschaften, die nicht in einem zusammengesetzten Index definiert sind, wird zur Auswertung der Abfrage eine Kombination aus zusammengesetztem Index und Bereichsindex verwendet. Das erfordert weniger RUs als bei ausschließlicher Verwendung von Bereichsindizes.
  • Wenn eine Eigenschaft einen Bereichsfilter besitzt (>, <, <=, >= oder !=), muss diese Eigenschaft im zusammengesetzten Index zuletzt definiert werden. Enthält eine Abfrage mehrere Bereichsfilter, empfiehlt sich ggf. die Verwendung mehrerer zusammengesetzter Indizes.
  • Wenn Sie einen zusammengesetzten Index erstellen, um Abfragen mit mehreren Filtern zu optimieren, hat die Reihenfolge (ORDER) des zusammengesetzten Index keine Auswirkungen auf die Ergebnisse. Diese Eigenschaft ist optional.

Betrachten Sie die folgenden Beispiele, in denen ein zusammengesetzter Index für die Eigenschaften „name“, „age“, und „timestamp“ definiert wird:

Zusammengesetzter Index Beispielabfrage Unterstützung durch zusammengesetzten Index?
(name ASC, age ASC) SELECT * FROM c WHERE c.name = "John" AND c.age = 18 Yes
(name ASC, age ASC) SELECT * FROM c WHERE c.name = "John" AND c.age > 18 Yes
(name ASC, age ASC) SELECT COUNT(1) FROM c WHERE c.name = "John" AND c.age > 18 Yes
(name DESC, age ASC) SELECT * FROM c WHERE c.name = "John" AND c.age > 18 Yes
(name ASC, age ASC) SELECT * FROM c WHERE c.name != "John" AND c.age > 18 No
(name ASC, age ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 123049923 Yes
(name ASC, age ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp = 123049923 No
(name ASC, age ASC) and (name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp > 123049923 Yes

Abfragen mit einem Filter und „ORDER BY“

Wenn eine Abfrage nach einer oder mehreren Eigenschaften filtert und verschiedene Eigenschaften in der ORDER BY-Klausel enthält, kann es hilfreich sein, die Eigenschaften im Filter der ORDER BY-Klausel hinzuzufügen.

Durch Hinzufügen der Eigenschaften im Filter zur ORDER BY-Klausel kann beispielsweise die folgende Abfrage umgeschrieben werden, um einen zusammengesetzten Index anzuwenden:

Abfrage mit Bereichsindex:

SELECT *
FROM c 
WHERE c.name = "John" 
ORDER BY c.timestamp

Abfrage mit zusammengesetztem Index:

SELECT * 
FROM c 
WHERE c.name = "John"
ORDER BY c.name, c.timestamp

Die gleichen Abfrageoptimierungen können für alle ORDER BY-Abfragen mit Filtern generalisiert werden. Beachten Sie dabei jedoch, dass einzelne zusammengesetzte Indizes maximal einen einzelnen Bereichsfilter unterstützen können.

Abfrage mit Bereichsindex:

SELECT * 
FROM c 
WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 1611947901 
ORDER BY c.timestamp

Abfrage mit zusammengesetztem Index:

SELECT * 
FROM c 
WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 1611947901 
ORDER BY c.name, c.age, c.timestamp

Außerdem können Sie zusammengesetzte Indizes verwenden, um Abfragen mit Systemfunktionen und „ORDER BY“ zu optimieren:

Abfrage mit Bereichsindex:

SELECT * 
FROM c 
WHERE c.firstName = "John" AND Contains(c.lastName, "Smith", true) 
ORDER BY c.lastName

Abfrage mit zusammengesetztem Index:

SELECT * 
FROM c 
WHERE c.firstName = "John" AND Contains(c.lastName, "Smith", true) 
ORDER BY c.firstName, c.lastName

Bei der Erstellung zusammengesetzter Indizes für die Optimierung einer Abfrage mit Filter und ORDER BY-Klausel muss Folgendes berücksichtigt werden:

  • Wenn Sie für eine Abfrage mit einem Filter für eine Eigenschaft und einer separaten ORDER BY-Klausel mit einer anderen Eigenschaft keinen zusammengesetzten Index definieren, wird die Abfrage trotzdem erfolgreich ausgeführt. Mit einem zusammengesetzten Index beansprucht die Abfrage allerdings weniger RUs – insbesondere, wenn die Eigenschaft in der ORDER BY-Klausel eine hohe Kardinalität besitzt.
  • Wenn die Abfrage nach Eigenschaften filtert, müssen diese Eigenschaften zuerst in der ORDER BY-Klausel angegeben werden.
  • Wenn die Abfrage nach mehreren Eigenschaften filtert, müssen die Gleichheitsfilter die ersten Eigenschaften in der ORDER BY-Klausel sein.
  • Wenn die Abfrage nach mehreren Eigenschaften filtert, kann pro zusammengesetztem Index maximal ein einzelner Bereichsfilter oder eine einzelne Systemfunktion verwendet werden. Die im Bereichsfilter oder in der Systemfunktion verwendete Eigenschaft muss im zusammengesetzten Index zuletzt definiert werden.
  • Die Überlegungen im Zusammenhang mit der Erstellung zusammengesetzter Indizes für ORDER BY-Abfragen mit mehreren Eigenschaften und für Abfragen mit Filtern für mehrere Eigenschaften gelten weiterhin.
Zusammengesetzter Index Beispiel einer ORDER BY-Abfrage Unterstützung durch zusammengesetzten Index?
(name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" ORDER BY c.name ASC, c.timestamp ASC Yes
(name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" AND c.timestamp > 1589840355 ORDER BY c.name ASC, c.timestamp ASC Yes
(timestamp ASC, name ASC) SELECT * FROM c WHERE c.timestamp > 1589840355 AND c.name = "John" ORDER BY c.timestamp ASC, c.name ASC No
(name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC, c.name ASC No
(name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC No
(age ASC, name ASC, timestamp ASC) SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.age ASC, c.name ASC,c.timestamp ASC Yes
(age ASC, name ASC, timestamp ASC) SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.timestamp ASC No

Abfragen mit einem Filter und einem Aggregat

Wenn eine Abfrage nach einer oder mehreren Eigenschaften filtert und eine Aggregatsystemfunktion aufweist, kann es hilfreich sein, einen zusammengesetzten Index für die Eigenschaften im Filter und in der Aggregatsystemfunktion zu erstellen. Diese Optimierung betrifft die Systemfunktionen SUM und AVG.

Bei der Erstellung zusammengesetzter Indizes für die Optimierung einer Abfrage mit einem Filter und einer Aggregatsystemfunktion muss Folgendes berücksichtigt werden:

  • Zusammengesetzte Indizes sind beim Ausführen von Abfragen mit Aggregaten optional. Mit einem zusammengesetzten Index beansprucht die Abfrage allerdings weniger RUs.
  • Wenn die Abfrage nach mehreren Eigenschaften filtert, müssen die Gleichheitsfilter die ersten Eigenschaften im zusammengesetzten Index sein.
  • Sie können pro zusammengesetztem Index maximal über einen Bereichsfilter verfügen, und dieser muss in der Eigenschaft in der Aggregatsystemfunktion enthalten sein.
  • Die Eigenschaft in der Aggregatsystemfunktion muss im zusammengesetzten Index zuletzt definiert werden.
  • Die order (ASC oder DESC) spielt keine Rolle.
Zusammengesetzter Index Beispielabfrage Unterstützung durch zusammengesetzten Index?
(name ASC, timestamp ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" Yes
(timestamp ASC, name ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" No
(name ASC, timestamp ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name > "John" No
(name ASC, age ASC, timestamp ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age = 25 Yes
(age ASC, timestamp ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age > 25 No

Zusammengesetzte Indizes mit einem Arrayplatzhalter

Im Folgenden finden Sie ein Beispiel für einen zusammengesetzten Index, der einen Arrayplatzhalter enthält.

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {  
            "path":"/*"
        }
    ],
    "excludedPaths":[],
    "compositeIndexes":[  
        [  
            {"path":"/familyname", "order":"ascending"},
            {"path":"/children/[]/age", "order":"descending"}
        ]
    ]
}

Die folgende Beispielabfrage kann von diesem zusammengesetzten Index profitieren:

SELECT r.id
FROM root r
JOIN ch IN r.children
WHERE r.familyname = 'Anderson' AND ch.age > 20

Ändern der Indizierungsrichtlinie

Die Indizierungsrichtlinie eines Containers kann jederzeit im Azure-Portal oder mit einem der unterstützten SDKs aktualisiert werden. Die Aktualisierung einer Indizierungsrichtlinie löst eine Transformation vom alten Index auf den neuen aus. Dies erfolgt online und direkt (sodass während des Vorgangs kein zusätzlicher Speicherplatz verbraucht wird). Die alte Indizierungsrichtlinie wird effizient in die neue Richtlinie transformiert, ohne die Schreibverfügbarkeit, Leseverfügbarkeit oder den Durchsatz, der für den Container bereitgestellt wird, zu beeinträchtigen. Die Indextransformation ist ein asynchroner Vorgang. Der erforderliche Zeitaufwand hängt vom bereitgestellten Durchsatz, der Anzahl der Elemente und ihrer Größe ab. Wenn mehrere Indexierungsrichtlinien aktualisiert werden müssen, empfiehlt es sich, alle Änderungen in einem einzigen Vorgang durchzuführen, damit die Indextransformation so schnell wie möglich abgeschlossen werden kann.

Wichtig

Die Indextransformation ist ein Vorgang, der Anforderungseinheiten verbraucht, und das Aktualisieren der Indexrichtlinie ist ein RU-gebundener Vorgang. Wenn ein Indizierungsausdruck fehlt, werden die Kunden feststellen, dass ihre Abfragen insgesamt mehr RUs verbrauchen.

Hinweis

Sie können den Status der Indextransformation im Azure-Portal oder mit einem der SDKs nachverfolgen.

Sie hat keine Auswirkungen auf die Schreibverfügbarkeit während der Indextransformationen. Die Indextransformation verwendet Ihre bereitgestellten RUs, allerdings mit einer niedrigeren Priorität als die CRUD-Vorgänge oder -Abfragen.

Das Hinzufügen neuer indizierter Pfade hat keine Auswirkungen auf die Leseverfügbarkeit. Abfragen verwenden neue indizierte Pfade erst dann, wenn eine Indextransformation abgeschlossen ist. Anders ausgedrückt: Beim Hinzufügen eines neuen indizierten Pfads weisen Abfragen, die von diesem indizierten Pfad profitieren, vor und während der Indextransformation die gleiche Leistung auf. Nachdem die Indextransformation abgeschlossen ist, beginnt die Abfrage-Engine mit der Verwendung der neuen indizierten Pfade.

Beim Entfernen indizierter Pfade sollten Sie alle Änderungen in einer Transformation für Indizierungsrichtlinien gruppieren. Wenn Sie im Zuge einer einzigen Indizierungsrichtlinienänderung mehrere Indizes entfernen, stellt die Abfrage-Engine konsistente und vollständige Ergebnisse im Rahmen der Indextransformation bereit. Wenn Sie Indizes jedoch über mehrere Indizierungsrichtlinienänderungen entfernen, stellt die Abfrage-Engine keine konsistenten oder vollständigen Ergebnisse bereit, bis alle Indextransformationen abgeschlossen sind. Die meisten Entwickler löschen keine Indizes und versuchen dann sofort, Abfragen auszuführen, die diese Indizes verwenden, sodass diese Situation in der Praxis eher unwahrscheinlich ist.

Wenn Sie einen indizierten Pfad löschen, wird er von der Abfrage-Engine umgehend nicht mehr verwendet. Stattdessen wird eine vollständige Überprüfung ausgeführt.

Hinweis

Sie sollten nach Möglichkeit versuchen, mehrere entfernte Indizierungen in einer einzelnen Indizierungsrichtlinienänderung zu gruppieren.

Wichtig

Das Entfernen eines Index hat sofortige Auswirkungen, während das Hinzufügen eines neuen Index einige Zeit in Anspruch nimmt, da hierbei eine Indizierungstransformation erforderlich ist. Wenn Sie einen Index durch einen anderen ersetzen (z. B. einen Index für eine einzelne Eigenschaft durch einen zusammengesetzten Index), fügen Sie zuerst den neuen Index hinzu, und warten Sie dann, bis die Indextransformation abgeschlossen ist, bevor Sie den vorherigen Index aus der Indizierungsrichtlinie entfernen. Andernfalls hat dies negative Auswirkungen auf Ihre Fähigkeit, den vorherigen Index abzufragen, und kann aktive Workloads unterbrechen, die auf den vorherigen Index verweisen.

Indizierungsrichtlinien und Gültigkeitsdauer

Die Verwendung des TTL-Features (Time-to-Live) erfordert die Indizierung. Dies bedeutet Folgendes:

  • Es ist nicht möglich, die TTL für einen Container zu aktivieren, wenn dessen Indizierungsmodus auf none festgelegt ist.
  • Es ist nicht möglich, den Indizierungsmodus für einen Container, in dem die TTL aktiviert ist, auf „Keine“ festzulegen.

Für Szenarien, in denen kein Eigenschaftenpfad indiziert werden muss, aber die TTL erforderlich ist, können Sie eine Indizierungsrichtlinie verwenden, bei der der Indizierungsmodus auf consistent festgelegt ist, keine Pfade eingeschlossen sind und /* der einzige ausgeschlossene Pfad ist.