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 vonheadquarters
lautet/headquarters/employees/?
.Der
country
-Pfad vonlocations
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.
Vektorindizes
Hinweis
Sie müssen sich für die Previewfunktion „Azure Cosmos DB – NoSQL-Vektorindex“ registrieren, um eine Vektorindizierungsrichtlinie 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 |
Einige Punkte sind zu beachten:
Die Indextypen
flat
undquantizedFlat
Indextypen verwenden den Index von Azure Cosmos DB, um jeden Vektor zu speichern und zu lesen, wenn eine Vektorsuche ausgeführt wird. Vektorsuchen mit einemflat
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 der505
Dimensionen für Vektoren in einem flachen Index.Der
quantizedFlat
Index speichert quantisierte (komprimierte) Vektoren im Index. Vektorsuchen mitquantizedFlat
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 mitquantized flat
sollten jedoch eine geringere Latenz, einen höheren Durchsatz und niedrigere RU-Kosten als Vektorsuchen in einemflat
-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 alsquantizedFlat
oderflat
.
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. Vektorindizes müssen auch zum Zeitpunkt der Containererstellung definiert werden und können nach der Erstellung nicht mehr geändert werden. In einer zukünftigen Version können Vektorindizes geändert werden.
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.
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 derORDER 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 derORDER 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
oderDESC
) 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 |
Ä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
Indextransformation ist ein Vorgang, der Anforderungseinheiten verbraucht.
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.