Freigeben über


Indizierungsrichtlinien in Cosmos DB in Microsoft Fabric (Vorschau)

Von Bedeutung

Dieses Feature befindet sich in der Vorschauphase.

Cosmos DB ist eine schemaagnostische Datenbank, mit der Sie ihre Anwendung durchlaufen können, ohne sich mit der Schema- oder Indexverwaltung befassen zu müssen. Die Indizierung in Cosmos DB in Microsoft Fabric wurde entwickelt, um eine schnelle und flexible Abfrageleistung bereitzustellen, unabhängig davon, wie sich Ihre Daten entwickeln. In Cosmos DB in Fabric verfügt jeder Container über eine Indizierungsrichtlinie, die festlegt, wie die Elemente des Containers indiziert werden sollen. Die standardmäßige Indizierungsrichtlinie für neu erstellte Container indiziert sämtliche Eigenschaften jedes Elements und erzwingt Bereichsindizes für jede Zeichenfolge oder Zahl. Diese Standardkonfiguration ermöglicht es Ihnen, eine gute Abfrageleistung zu erzielen, ohne vorher über die Indizierung und Die Indexverwaltung nachdenken 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.

Indizierungsmodus

Cosmos DB unterstützt zwei Indizierungsmodi:

  • Konsistent: Der Index wird synchron aktualisiert, wenn Sie Elemente erstellen, aktualisieren oder löschen.

  • 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 Sammeloperationen kann der Indexmodus auf Consistent gesetzt und anschließend mithilfe der IndexTransformationProgress-Funktion im SDK überwacht werden, bis er abgeschlossen ist.

Hinweis

Cosmos DB unterstützt auch einen Lazy-Indizierungsmodus. Die faule Indizierung führt Aktualisierungen des Indexes auf einer niedrigeren Prioritätsebene durch, wenn die Engine keine andere Arbeit ausführt. Dieses Verhalten kann zu inkonsistenten oder unvollständigen Abfrageergebnissen führen. Wenn Sie beabsichtigen, einen Cosmos DB-Container abzufragen, sollten Sie keine faule Indizierung auswählen. Neue Container können kein Lazy Indexing auswählen.

Indexgröße

In Cosmos DB besteht der gesamte verbrauchte Speicher aus der 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.

  • Die Systemeigenschaften id und _ts werden immer indiziert, wenn der Indizierungsmodus des Containers konsistent ist.

  • Die Systemeigenschaften id und _ts sind nicht in der Beschreibung der indizierten Pfade für eine Containerrichtlinie enthalten. Dieser Ausschluss ist beabsichtigt, da diese Systemeigenschaften standardmäßig indiziert sind und dieses Verhalten nicht deaktiviert werden kann.

Hinweis

Der Partitionsschlüssel (es sei denn, er ist auch /id) ist nicht indiziert und sollte im Index enthalten sein.

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.

Betrachten Sie dieses JSON-Element erneut:

{
  "locations": [
    { "country": "Germany", "city": "Berlin" },
    { "country": "France", "city": "Paris" }
  ],
  "headquarters": { "country": "Belgium", "employees": 250 },
  "exports": [
    { "city": "Moscow" },
    { "city": "Athens" }
  ]
}

Diese Indizierungsrichtlinie führt zu folgenden Indizierungspfaden:

Pfad Wert
/locations/0/country "Germany"
/locations/0/city "Berlin"
/locations/1/country "France"
/locations/1/city "Paris"
/headquarters/country "Belgium"
/headquarters/employees 250
/exports/0/city "Moscow"
/exports/1/city "Athens"

Diese Pfade werden mit den folgenden Ergänzungen definiert:

  • Ein Pfad zu einem Skalarwert (Zeichenfolge oder Zahl) endet auf /?.

  • Elemente aus einem Array werden durch die /[] Notation (anstelle von /0, /1usw.) zusammen adressiert.

  • Der Platzhalter /* kann verwendet werden, um alle Elemente unter einem Knoten einzufügen.

Eine Basisindexrichtlinie für das Beispielelement kann folgende Optimierungen umfassen:

  • Der headquarters-Pfad von employees lautet /headquarters/employees/?.

  • Der locations-Pfad von country 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. Dieser Ansatz wird empfohlen, da Cosmos DB proaktiv jede neue Eigenschaft indizieren kann, die Ihrem Modell hinzugefügt werden kann.

  • Schließen Sie den Stammpfad aus, um einzelne Pfade einzuschließen, die indiziert werden müssen. Der Partitionsschlüssel-Eigenschaftspfad ist nicht standardmäßig mit der ausgeschlossenen 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.

Weitere Informationen finden Sie unter Beispielindizierungsrichtlinien.

Vorrang beim Einschließen/Ausschließen

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

Betrachten Sie dieses 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 werden alle Daten im /food/ingredients Pfad oder geschachtelt innerhalb des Pfads vom Index ausgeschlossen. Die Ausnahme wären Daten innerhalb des eingeschlossenen Pfads /food/ingredients/nutrition/*. Diese würden indiziert werden.

Hier sind einige Regeln für die Rangfolge von eingeschlossenen und ausgeschlossenen Pfaden in Cosmos DB:

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

  • /? ist präziser als /*. Zum Beispiel ist /a/? präziser als /a/*, daher hat /a/? Vorrang.

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

Volltextindizes

Volltextindizes ermöglichen die Volltextsuche und bewertung effizient mithilfe des Indexes. 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. Beispiel:

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

Von Bedeutung

Eine Volltext-Indizierungsrichtlinie muss sich in dem Pfad befinden, der in der Volltextrichtlinie des Containers definiert ist. Weitere Informationen finden Sie in der Volltextsuche.

Vektorindizes

Vektorindizes erhöhen die Effizienz beim Ausführen von Vektorsuchen mithilfe der VECTORDISTANCE Systemfunktion. Vektorsuchen haben geringere Latenz, einen höheren Durchsatz und weniger Anforderungseinheitsverbrauch (RU), wenn sie einen Vektorindex anwenden. 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. Dieser Typ kann die Latenz und den Durchsatz auf Kosten einer kleinen Genauigkeit verbessern. 4096
diskANN Erstellt einen Index basierend auf DiskANN für schnelle und effiziente Näherungssuche. 4096

Von Bedeutung

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

Einige Punkte sind zu beachten:

  • Die flat Indextypen und quantizedFlat Indextypen verwenden den Index von Cosmos DB, um jeden Vektor während einer Vektorsuche zu speichern und zu lesen. Vektorsuchen mit einem flat-Index sind Brute-Force-Suchen und bieten 100% Genauigkeit oder Recall. Diese Genauigkeit bedeutet, dass die Suche immer die ähnlichsten Vektoren im Dataset findet. Ein flat Index unterstützt jedoch Vektoren mit bis zu 505 dimensionen.

    • Der quantizedFlat Index speichert quantisierte (komprimierte) Vektoren im Index. Vektorsuchen mit dem quantizedFlat-Index sind ebenfalls Brute-Force-Suchvorgänge, ihre Genauigkeit kann jedoch etwas niedriger 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. Dieser Typ ist eine gute Option für Szenarien, in denen Sie Abfragefilter verwenden, um die Vektorsuche auf eine relativ kleine Gruppe von Vektoren einzugrenzen. In diesem Szenario ist eine hohe Genauigkeit 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 Latenzzeiten, den höchsten Durchsatz und die niedrigsten RU-Kosten für Abfragen 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, Default=dynamic (System entscheidet), Max=512). Das Festlegen dieser Größe könnte zu höheren Genauigkeitsvektorsuchen auf Kosten höherer RU-Kosten und höherer Latenz führen. Dieser Kompromiss gilt sowohl für quantizedFlat- als auch DiskANN-Indextypen.

    • indexingSearchListSize: legt fest, wie viele Vektoren während der Indexerstellung durchsucht werden sollen. Min=10, Standard=100, Max=500. Das Festlegen dieser Größe könnte zu höheren Genauigkeitsvektorsuchen auf Kosten längerer Indexbuildzeiten und höherer Vektorlatenz führen. Dieses Merkmal gilt nur für DiskANN Indizes.

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

Von Bedeutung

Der Vektorpfad sollte dem excludedPaths Abschnitt der Indizierungsrichtlinie hinzugefügt werden, um eine optimierte Leistung für die Einfügung sicherzustellen. Das Nicht-Hinzufügen des Vektorpfads zu excludedPaths führt zu höheren RU-Kosten und einer erhöhten Latenz bei Vektoreinfügungen.

Eine Vektorindizierungsrichtlinie muss sich auch auf dem Pfad befinden, der in der Vektorrichtlinie des Containers definiert ist. Weitere Informationen finden Sie unter Vektorrichtlinien.

Räumliche Indizes

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:

  • Punkt

  • Polygon

  • MultiPolygon

  • LineString

Standardmäßig erstellt Cosmos DB keine räumlichen Indizes. Um räumliche SQL-integrierte Funktionen zu verwenden, erstellen Sie einen räumlichen Index für die erforderlichen Eigenschaften. Weitere Informationen finden Sie unter räumlichen Indizes.

Tupelindizes

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

Hinweis

Im Gegensatz zu eingeschlossenen oder ausgeschlossenen Pfaden können Sie keinen Pfad mit dem /*-Platzhalter erstellen. Jeder Tupelpfad muss mit /?. 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.

Array-Tupelpfade werden im includedPaths Abschnitt mithilfe der folgenden Schreibweise definiert: <path prefix>/[]/{<tuple 1>, <tuple 2>, …, <tuple n>}/?

Beachten Sie die folgenden wichtigen Regeln für Array-Tupel:

  • Jeder Teil des Tupels wird durch ein Komma getrennt.

  • Der erste Teil, das Pfadpräfix, ist der Pfad, der zwischen den Tupeln gemeinsam ist. Es ist der Pfad vom Stamm zum Array. In unserem Beispiel ist es /events.

  • Nach dem ersten Teil sollte das Tupel den Array-Wildcard-Bezeichner [] enthalten. Alle Array-Tupelpfade sollten einen Array-Wildcardbezeichner vor dem Tupelbezeichner {}aufweisen.

  • Der nächste Teil gibt Tupel mithilfe des Tupelbezeichners {} an.

  • Das Tuple muss dieselbe Pfadspezifikation wie die anderen Indexpfade aufweisen, wobei einige wenige Ausnahmen gelten:

    • Tupel sollten nicht mit dem führenden / beginnen.

    • Tupel sollten keine Array-Wildcards haben.

    • Tupel sollten nicht mit ? oder * enden.

    • ? ist das letzte Segment in einem Tupelpfad und sollte unmittelbar nach dem Tupelbezeichnersegment angegeben werden.

Diese Spezifikation ist beispielsweise ein gültiger Tupelpfad: /events/[]/{name, category}/?

Hier sind einige weitere gültige Beispiele für Pfade von Array-Tupeln:

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

Hier sind einige Beispiele für ungültige Array-Tupelpfade mit Erläuterungen:

Ungültiger Pfad Erklärung
/events/[]/{name/[]/first, category}/? Eines der Tupel enthält einen Arrayplatzhalter.
/events/[]/{name, category}/* Das letzte Segment im Array-Tupel-Pfad sollte ? und nicht * sein.
/events/[]/{{name, first},category}/? Der Tupelbezeichner ist geschachtelt.
/events/{name, category}/? Der Arrayplatzhalter fehlt vor dem Tupelbezeichner.
/events/[]/{/name,/category}/? Tupel müssen mit einem vorangestellten / beginnen.
/events/[]/{name/?,category/?}/? Tupel müssen mit einer ? enden
/city/[]/events/[]/{name, category}/? Das Pfadpräfix als zwei Array-Wildcards

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, sodass Sie bei Bedarf zusammengesetzte Indizes hinzufügen sollten.

Sie können den /* Wildcard nicht in zusammengesetzten Indexpfaden verwenden. Jeder zusammengesetzte Pfad endet automatisch mit /?, sodass Sie ihn nicht hinzufügen müssen. Zusammengesetzte Pfade müssen auf einen skalaren Wert verweisen, bei dem es sich um den einzigen wert handelt, der im zusammengesetzten Index enthalten ist. Wenn kein zusammengesetzter Indexpfad in einem Element vorhanden ist oder auf einen nichtkalaren Wert zeigt, fügt Cosmos DB dem Index einen Wert hinzu, um anzuzeigen, dass der Pfad nicht definiert ist.

Beim Definieren eines zusammengesetzten Indexes geben Sie diese beiden Komponenten an:

  • Zwei oder mehr Eigenschaftspfade, definiert in einer bestimmten Reihenfolge, die sich auf die Verwendung des zusammengesetzten Indexes auswirkt.

  • Die Reihenfolge, die entweder aufsteigend oder absteigend definiert ist.

Wenn Sie einen zusammengesetzten Index hinzufügen, verwendet die Abfrage vorhandene Bereichsindizes, bis die neue zusammengesetzte Indexzufügung abgeschlossen ist. Daher kann es sein, dass beim Hinzufügen eines zusammengesetzten Index nicht sofort Leistungsverbesserungen erkennbar sind.

Tipp

Es ist möglich, den Fortschritt der Indextransformation mithilfe eines der Software Development Kits (SDKs) nachzuverfolgen.

ORDER BY fragt mehrere Eigenschaften ab:

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 Beispielabfrage ORDER BY Wird von Composite Index unterstützt?
(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
  container c
WHERE
  c.name = "John" AND c.age > 18

Diese Abfrage ist effizienter und benötigt weniger Zeit und weniger Anforderungseinheiten (RUs), wenn ein zusammengesetzter Index auf (name ASC, age ASC) angewendet werden 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
  container 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.

Die folgenden Überlegungen werden beim Erstellen zusammengesetzter Indizes für Abfragen mit Filtern für mehrere Eigenschaften verwendet:

  • Filterausdrücke können mehrere zusammengesetzte Indizes verwenden.

  • Die Eigenschaften im Abfragefilter sollten mit den Eigenschaften im zusammengesetzten Index übereinstimmen. Wenn sich eine Eigenschaft im zusammengesetzten Index befindet, aber nicht als Filter in der Abfrage enthalten ist, verwendet die Abfrage nicht den zusammengesetzten Index.

  • Wenn eine Abfrage nach Eigenschaften filtert, die nicht in einem zusammengesetzten Index enthalten sind, werden eine Kombination aus zusammengesetzten Indizes und Bereichsindizes verwendet, um die Abfrage auszuwerten. Dieser Ansatz verbraucht weniger RUs als ausschließlich auf Bereichsindizes zu setzen.

  • 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.

  • Beim Erstellen eines zusammengesetzten Indexes zum Optimieren von Abfragen mit mehreren Filtern hat der ORDER zusammengesetzte 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 Wird von Composite Index unterstützt?
(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
  container c
WHERE
  c.name = "John"
ORDER BY
  c.timestamp

Abfrage mit zusammengesetztem Index:

SELECT
  *
FROM
  container 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
  container c
WHERE
  c.name = "John" AND
  c.age = 18 AND
  c.timestamp > 1611947901
ORDER BY
  c.timestamp

Abfrage mit zusammengesetztem Index:

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

Darüber hinaus können Sie zusammengesetzte Indizes verwenden, um Abfragen mit Systemfunktionen zu optimieren und ORDER BY:

Abfrage mit Bereichsindex:

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

Abfrage mit zusammengesetztem Index:

SELECT
  *
FROM
  container 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 keinen zusammengesetzten Index für eine Abfrage mit einem Filter für eine Eigenschaft und einer separaten ORDER BY Klausel mit einer anderen Eigenschaft definieren, ist die Abfrage weiterhin erfolgreich. 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 Beispielabfrage ORDER BY Wird von Composite Index unterstützt?
(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 gilt für die SUM Funktionen und AVG Systemfunktionen.

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 Wird von Composite Index unterstützt?
(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

Hier ist ein Beispiel für einen zusammengesetzten Index, der einen Array-Wildcard 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 VALUE
  p.id
FROM
  products p
JOIN
  t IN p.tags
WHERE
  p.category = 'apparel' AND
  p.order > 20

Ändern der Indizierungsrichtlinie

Eine Aktualisierung der Indizierungsrichtlinie löst eine Transformation vom alten Index in den neuen aus. Diese Transformation wird an Ort und Stelle und online durchgeführt. Während des Vorgangs wird kein zusätzlicher Speicherplatz verbraucht. 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 Sie mehrere Indizierungsrichtlinienaktualisierungen vornehmen müssen, führen Sie alle Änderungen in einem einzelnen Vorgang aus. Mit diesem Ansatz kann die Indextransformation schneller abgeschlossen werden.

Von Bedeutung

Indextransformation ist ein Vorgang, der Anforderungseinheiten verbraucht. Sie können den Fortschritt und den Verbrauch des Indextransformationsvorgangs mithilfe eines der SDKs nachverfolgen.

Während einer Indextransformation gibt es keine Auswirkungen auf die Schreibverfügbarkeit. Die Indextransformation verwendet Ihre bereitgestellten RUs, allerdings mit einer niedrigeren Priorität als die CRUD-Vorgänge oder -Abfragen.

Beim Hinzufügen neuer indizierter Pfade gibt es keine Auswirkung auf die Verfügbarkeit beim Lesen. Abfragen verwenden neue indizierte Pfade nur, nachdem die Indextransformation abgeschlossen wurde. 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 jedoch Indizes durch mehrere Indizierungsrichtlinienänderungen entfernen, stellt das Abfragemodul erst dann konsistente oder vollständige Ergebnisse bereit, wenn alle Indextransformationen abgeschlossen sind. Die meisten Entwickler legen keine Indizes ab und versuchen dann sofort, Abfragen auszuführen, die diese Indizes verwenden. In der Praxis ist diese Situation unwahrscheinlich.

Wenn Sie einen indizierten Pfad ablegen, beendet die Abfrage-Engine sofort die Verwendung von diesem und führt stattdessen einen vollständigen Scan durch. Gruppieren Sie nach Möglichkeit immer mehrere Entfernungen von Indizes in einer einzelnen Änderung der Indexierungsrichtlinie.

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. 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, wenn Sie einen Index durch einen anderen ersetzen. Folgen Sie beispielsweise dieser Strategie, wenn Sie einen einzelnen Eigenschaftenindex durch einen zusammengesetzten Index ersetzen. Andernfalls wirkt sich dieser Fehler negativ auf ihre Fähigkeit aus, den vorherigen Index abzufragen, und kann alle aktiven Arbeitslasten, die auf den vorherigen Index verweisen, unterbrechen.

Indizierungsrichtlinien und Gültigkeitsdauer

Für die Nutzung der Time-to-Live (TTL) Funktion ist eine Indizierung erforderlich.

Dies bedeutet folgendes:

  • Es ist nicht möglich, TTL für einen Container zu aktivieren, in dem der Indizierungsmodus auf none gesetzt ist.

  • Es ist nicht möglich, den Indizierungsmodus auf "None" für einen Container festzulegen, in dem TTL aktiviert ist.

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.

Nächster Schritt