Indizierung in Cosmos DB (in Azure und Fabric)

Cosmos DB (in Azure und Fabric) ist eine schemaagnostische Datenbank, mit der Sie ihre Anwendung durchlaufen können, ohne sich mit Schema- oder Indexverwaltung befassen zu müssen. Diese Funktionalität wird auch als Schema beim Lesen bezeichnet, was bedeutet, dass Cosmos DB beim Schreiben in die Datenbank kein Schema für Ihre Daten erzwingt. Ihr Schema wird in den Klassen definiert, die Sie innerhalb Ihrer Anwendung erstellen, während Sie Daten aus der Datenbank während Lese- oder Schreibvorgängen deserialisieren.

Die Indizierung innerhalb von Cosmos DB in Microsoft Fabric ist darauf ausgelegt, eine schnelle und flexible Abfrageleistung bereitzustellen, unabhängig davon, wie sich Ihre Daten entwickeln. Standardmäßig indiziert Cosmos DB automatisch jede Eigenschaft für alle Elemente in Ihrem Container, ohne dass Schemas definiert oder sekundäre Indizes konfiguriert werden müssen.

Konzeptioneller Baum

Bei jedem Speichern eines Elements in einem Container wird dessen Inhalt als ein JSON-Dokument projiziert und anschließend in eine strukturierte Darstellung konvertiert. Diese Konvertierung bedeutet, dass jede Eigenschaft dieses Elements als Knoten in einer Struktur dargestellt wird. Als übergeordnetes Element für alle Eigenschaften auf oberster Ebene des Elements wird ein Pseudostammknoten erstellt. Die Blattknoten enthalten die eigentlichen Skalarwerte eines Elements.

Betrachten Sie z. B. dieses Element:

{
  "id": "00000000-0000-0000-0000-000000004368",
  "name": "Cofaz Jacket",
  "tags": [
    { "category": "clothing", "type": "jacket" },
    { "category": "outdoor", "type": "winter" }
  ],
  "inventory": { "warehouse": "Seattle", "quantity": 50 },
  "distributors": [
    { "name": "Contoso" },
    { "name": "AdventureWorks" }
  ]
}

Diese konzeptionelle Baumstruktur stellt das JSON-Beispielelement dar.

  • id: 00000000-0000-0000-0000-000000004368
  • name: Cofaz Jacket
  • tags
    • 0
      • category: clothing
      • type: jacket
    • 1
      • category: outdoor
      • type: winter
  • inventory
    • warehouse: Seattle
    • quantity: 50
  • distributors
    • 0
      • name: Contoso
    • 1
      • name: AdventureWorks

Diagramm der Baumdarstellung eines Elements in Cosmos DB. Das Diagramm zeigt die hierarchische Struktur eines JSON-Elements in Cosmos DB mit Zweigen für ID, Name, Tags, Inventar und Eigenschaften von Distributoren.

Achten Sie darauf, wie Arrays in der Struktur codiert werden: Jeder Eintrag in einem Array erhält einen Zwischenknoten mit dem Index dieses Eintrags innerhalb des Arrays. Beispielsweise ist 0 der erste Eintrag und der zweite Eintrag ist 1.

Eigenschaftspfade

Cosmos DB wandelt Elemente in Bäume um, da es dem System ermöglicht, mithilfe ihrer Pfade innerhalb dieser Bäume auf Eigenschaften zu verweisen. Um den Pfad für eine Eigenschaft abzurufen, können wir die Struktur vom Stammknoten bis zu dieser Eigenschaft durchlaufen und dabei die Bezeichnungen aller durchlaufenen Knoten verketten.

Dies sind die Pfade für jede Eigenschaft aus dem zuvor beschriebenen Beispielelement:

Pfad Wert
/id "00000000-0000-0000-0000-000000004368"
/name "Cofaz Jacket"
/tags/0/category "clothing"
/tags/0/type "jacket"
/tags/1/category "outdoor"
/tags/1/type "winter"
/inventory/warehouse "Seattle"
/inventory/quantity 50
/distributors/0/name "Contoso"
/distributors/1/name "AdventureWorks"

Cosmos DB indiziert effektiv den Pfad jeder Eigenschaft und den entsprechenden Wert, wenn ein Element geschrieben wird.

Indextypen in Cosmos DB

Cosmos DB unterstützt derzeit vier Arten von Indizes.

Sie können diese Indextypen beim Definieren der Indizierungsrichtlinie konfigurieren.

Bereichsindex

Die Bereichsindizes basieren auf einer geordneten baumähnlichen Struktur. Der Reichweiten-Indextyp wird für Folgendes verwendet:

  • Gleichheitsabfragen:

    SELECT
      *
    FROM
      container c
    WHERE
      c.property = 'value'
    
    SELECT
      *
    FROM
      container c
    WHERE
      c.property IN ("value1", "value2", "value3")
    
  • Gleichheitsvergleich bei einem Arrayelement

    SELECT
      *
    FROM
      container c
    WHERE
      ARRAY_CONTAINS(c.tags, "tag1")
    
  • Bereichsabfragen:

    SELECT
      *
    FROM
      container c
    WHERE
      c.property > 0
    

    Hinweis

    Funktioniert für >, <, >=, <=, !=

  • Überprüfung, ob eine Eigenschaft vorhanden ist:

    SELECT
      *
    FROM
      container c
    WHERE
      IS_DEFINED(c.property)
    
  • Stringsystemfunktionen:

    SELECT
      *
    FROM
      container c
    WHERE
      CONTAINS(c.property, "value")
    
    SELECT
      *
    FROM
      container c
    WHERE
      STRINGEQUALS(c.property, "value")
    
  • ORDER BY Abfragen:

    SELECT
      *
    FROM
      container c
    ORDER BY
      c.property
    
  • JOIN Abfragen:

    SELECT
      d
    FROM
      container c
    JOIN
      d IN c.properties
    WHERE
      d = 'value'
    

Range-Indizes können für Skalarwerte (Zeichenfolge oder Zahl) verwendet werden. Die standardmäßige Indizierungsrichtlinie für neu erstellte Container erzwingt Bereichsindizes für jede Zeichenfolge oder Zahl.

Hinweis

Eine ORDER BY Klausel, die von einer einzelnen Eigenschaft sortiert wird, benötigt immer einen Bereichsindex und schlägt fehl, wenn der pfad, auf den verwiesen wird, keinen hat. Ebenso benötigt eine ORDER BY Abfrage, die nach mehreren Eigenschaften sortiert wird, immer einen zusammengesetzten Index.

Räumlicher Index

Räumliche Indizes ermöglichen effiziente Abfragen von Geospatialobjekten wie Punkten, Linien, Polygonen und Multipolygons. Diese Abfragen verwenden ST_DISTANCE, ST_WITHIN, ST_INTERSECTS Schlüsselwörter. Im Folgenden finden Sie einige Beispiele für die Verwendung des räumlichen Indextyps:

  • Abfragen zum räumlichen Abstand:

    SELECT
      *
    FROM
      container c
    WHERE
      ST_DISTANCE(c.property, { "type": "Point", "coordinates": [0.0, 10.0] }) < 40
    
  • Räumliche Abfragen:

    SELECT
      *
    FROM
      container c
    WHERE
      ST_WITHIN(c.property, {"type": "Point", "coordinates": [0.0, 10.0] })
    
  • Abfragen zur räumlichen Überschneidung:

    SELECT
      *
    FROM
      container c
    WHERE
      ST_INTERSECTS(c.property, { 'type':'Polygon', 'coordinates': [[ [31.8, -5], [32, -5], [31.8, -5] ]]  })  
    

Räumliche Indizes können für korrekt formatierte GeoJSON-Objekte verwendet werden. Derzeit werden Point, LineString, Polygon und MultiPolygon unterstützt.

Zusammengesetzter Index

Zusammengesetzte Indizes erhöhen die Effizienz, wenn Sie Vorgänge für mehrere Felder durchführen. Der zusammengesetzte Indextyp wird für Folgendes verwendet:

  • ORDER BY fragt mehrere Eigenschaften ab:

    SELECT
      *
    FROM
      container c
    ORDER BY
      c.property1,
      c.property2
    
  • Abfragen mit einem Filter und ORDER BY. Diese Abfragen können einen zusammengesetzten Index verwenden, wenn die Filter-Eigenschaft der ORDER BY-Klausel hinzugefügt wird.

    SELECT
      *
    FROM
      container c
    WHERE
      c.property1 = 'value'
    ORDER BY
      c.property1,
      c.property2
    
  • Abfragen mit einem Filter auf zwei oder mehr Eigenschaften, bei denen mindestens eine Eigenschaft ein Gleichheitsfilter ist:

    SELECT
      *
    FROM
      container c
    WHERE
      c.property1 = 'value' AND
      c.property2 > 'value'
    

Solange ein Filter-Prädikat einen der Indextypen verwendet, wertet das Abfragemodul diese zuerst aus, bevor der Rest überprüft wird. Wenn Sie z. B. über eine SQL-Abfrage wie SELECT * FROM c WHERE c.department = "Information Technology" and CONTAINS(c.team, "Pilot") verfügen:

  • Diese Abfrage wendet zuerst einen Filter für Einträge an, bei denen department = "Information Technology" der Index verwendet wird. Anschließend werden alle department = "Information Technology" Einträge über eine nachfolgende Pipeline übergeben, um das CONTAINS Filter-Prädikat auszuwerten.

  • Sie können Abfragen beschleunigen und vollständige Containerscans vermeiden, wenn Sie Funktionen verwenden, die einen vollständigen Scan ausführen.CONTAINS Sie können weitere Filterprädikate hinzufügen, die den Index verwenden, um diese Abfragen zu beschleunigen. Die Reihenfolge der Filterklauseln ist nicht von Bedeutung. Die Abfrage-Engine ermittelt, welche Prädikate selektiver sind, und führt die Abfrage entsprechend aus.

Vektorindex

Vektorindizes erhöhen die Effizienz beim Ausführen von Vektorsuchen mithilfe der VECTORDISTANCE Systemfunktion. Vektorsuchen haben niedrigere Latenz, einen höheren Durchsatz und weniger RU-Verbrauch bei Verwendung eines Vektorindexes. Cosmos DB unterstützt alle Vektoreinbettungen (Text, Bild, Multimodal usw.) unter 4.096 Dimensionen in der Größe.

  • ORDER BY-Vektorsuchabfragen:

    SELECT TOP 10
      *
    FROM
      container c
    ORDER BY
      VECTORDISTANCE(c.vector1, c.vector2)
    
  • Projektion der Ähnlichkeitsbewertung in Vektorsuchabfragen:

    SELECT TOP 10
      c.name,
      VECTORDISTANCE(c.vector1, c.vector2) AS score
    FROM
      container c
    ORDER BY
      VECTORDISTANCE(c.vector1, c.vector2)
    
  • Bereichsfilter für die Ähnlichkeitsbewertung

    SELECT TOP 10
      *
    FROM
      container c
    WHERE
      VECTORDISTANCE(c.vector1, c.vector2) > 0.8
    ORDER BY
      VECTORDISTANCE(c.vector1, c.vector2)
    

Hinweis

Im Allgemeinen können Sie neue Pfadkonfigurationen hinzufügen oder vorhandene entfernen, aber Sie können die Einstellungen einer Vektor-Emebdding-Richtlinie oder Vektorindizierungsrichtlinie nicht ändern. Dazu müssen Sie zuerst die vorhandene Vektorrichtlinie und den Index ablegen und dann mit der neuen Konfiguration wieder hinzufügen.

Wie Abfragen Indizes verwenden

Es gibt fünf Möglichkeiten, wie die Abfrage-Engine Abfragefilter auswerten kann. Diese sind hier in absteigender Reihenfolge von der effizientesten zu der am wenigsten effizienten aufgelistet:

  • Indexsuche
  • Präziser Indexscan
  • Erweiterter Indexscan
  • Vollständiger Indexscan
  • Vollständiger Scan

Wenn Sie Eigenschaftenpfade indizieren, verwendet die Abfrage-Engine den Index automatisch so effizient wie möglich. Abgesehen von der Indizierung neuer Eigenschaftenpfade müssen Sie keine Konfigurationen durchführen, um die Verwendung des Index durch Abfragen zu optimieren. Die RU-Gebühr einer Abfrage setzt sich aus der RU-Gebühr für die Indexnutzung und der RU-Gebühr für das Laden von Elementen zusammen.

In der folgenden Tabelle sind die verschiedenen Verwendungsmöglichkeiten von Indizes in Cosmos DB zusammengefasst:

Suchtyp Description Allgemeine Beispiele Gebühr aus Indexnutzung Gebühren beim Laden von Elementen aus dem Transaktionsdatenspeicher
Indexsuche Lesen nur erforderlicher indizierter Werte und Laden nur übereinstimmender Elemente aus dem Transaktionsdatenspeicher Gleichheitsfilter, IN Konstant pro Gleichheitsfilter Erhöht sich basierend auf der Anzahl von Elementen in Abfrageergebnissen
Präziser Indexscan Binärsuche indizierter Werte und Laden nur übereinstimmender Elemente aus dem Transaktionsdatenspeicher Bereichsvergleiche (>, <, <=, oder >=), beginnt mit Vergleichbar mit Indexsuche, erhöht sich leicht basierend auf der Kardinalität indizierter Eigenschaften Erhöht sich basierend auf der Anzahl von Elementen in Abfrageergebnissen
Erweiterte Indexüberprüfung Optimierte Suche (jedoch weniger effizient als Binärsuche) indizierter Werte und Laden nur übereinstimmender Elemente aus dem Transaktionsdatenspeicher StartsWith (ohne Berücksichtigung der Groß-/Kleinschreibung), StringEquals (ohne Berücksichtigung der Groß-/Kleinschreibung) Erhöht sich leicht basierend auf der Kardinalität indizierter Eigenschaften Erhöht sich basierend auf der Anzahl von Elementen in Abfrageergebnissen
Vollständiger Indexscan Lesen eines eindeutigen Satzes indizierter Werte und Laden nur übereinstimmender Elemente aus dem Transaktionsdatenspeicher Enthält, EndetMit, RegexMatch, LIKE Erhöht sich linear basierend auf der Kardinalität indizierter Eigenschaften Erhöht sich basierend auf der Anzahl von Elementen in Abfrageergebnissen
Vollständige Überprüfung Laden aller Elemente aus dem Transaktionsdatenspeicher Oben, unten N/A Erhöht sich basierend auf der Anzahl von Elementen im Container

Beim Schreiben von Abfragen sollten Sie Filterprädikate verwenden, die den Index so effizient wie möglich nutzen. Wenn z. B. StartsWith oder Contains für Ihren Anwendungsfall geeignet ist, sollten Sie StartsWith auswählen, da hiermit statt eines vollständigen Indexscans ein präziser Indexscan durchgeführt wird.

Details zur Indexnutzung

Tipp

In diesem Abschnitt werden weitere Details zur Verwendung von Indizes für Abfragen behandelt. Diese Detailstufe ist nicht erforderlich, um zu erfahren, wie Sie mit Cosmos DB beginnen, aber für neugierige Benutzer detailliert dokumentiert sind. Wir beziehen uns auf das bereits früher in diesem Dokument erwähnte Beispiel.

Betrachten Sie diese beiden Beispielelemente:

[
  {
    "id": "00000000-0000-0000-0000-000000004368",
    "name": "Cofaz Jacket",
    "tags": [
      { "category": "clothing", "type": "jacket" },
      { "category": "outdoor", "type": "winter" }
    ],
    "inventory": { "warehouse": "Seattle", "quantity": 50 },
    "distributors": [
      { "name": "Contoso" },
      { "name": "AdventureWorks" }
    ]
  },
  {
    "id": "00000000-0000-0000-0000-000000004002",
    "name": "Potana bike",
    "tags": [
      { "category": "cycling", "type": "mountain" }
    ],
    "inventory": { "warehouse": "Seattle", "quantity": 30 },
    "distributors": [
      { "name": "Contoso" },
      { "name": "Fabrikam" },
      { "name": "Northwind" }
    ]
  }
]

Cosmos DB verwendet einen invertierten Index. Der Index ordnet jeden JSON-Pfad dem Satz von Elementen zu, die diesen Wert enthalten. Die Element-ID-Zuordnung wird auf vielen verschiedenen Indexseiten für den Container dargestellt. Hier sehen Sie eine Beispielabbildung eines invertierten Index für einen Container, der die beiden Beispielelemente enthält:

Pfad Wert Liste der Elementbezeichner
/tags/0/category clothing [00000000-0000-0000-0000-000000004368]
/tags/0/category cycling [00000000-0000-0000-0000-000000004002]
/tags/0/type jacket [00000000-0000-0000-0000-000000004368]
/tags/0/type mountain [00000000-0000-0000-0000-000000004002]
/tags/1/category outdoor [00000000-0000-0000-0000-000000004368]
/tags/1/type winter [00000000-0000-0000-0000-000000004368]
/inventory/warehouse Seattle [00000000-0000-0000-0000-000000004368, 00000000-0000-0000-0000-000000004002]
/inventory/quantity 30 [00000000-0000-0000-0000-000000004002]
/inventory/quantity 50 [00000000-0000-0000-0000-0000-000000004001]

Der invertierte Index verfügt über zwei wichtige Attribute:

  • Werte werden für einen bestimmten Pfad in aufsteigender Reihenfolge sortiert. Daher kann die Abfrage-Engine ORDER BY problemlos über den Index bedienen.

  • Die Abfrage-Engine kann für einen bestimmten Pfad den eindeutigen Satz möglicher Werte durchsuchen, um die Indexseiten zu ermitteln, die Ergebnisse enthalten.

Die Abfrage-Engine kann den invertierten Index auf vier verschiedene Arten nutzen:

Indexsuche

Betrachten Sie die folgende Abfrage:

SELECT
  tag
FROM
  tag IN product.tags
WHERE
  tag.category = 'outdoor'

Das Abfrage-Prädikat (Filtern nach Elementen, bei denen ein Tag "outdoor" als Kategorie hat) würde dem hier genannten Pfad entsprechen:

  • tags
    • 1
      • category: outdoor

Diagramm einer Durchquerung (Suche) mit Hervorhebung der Pfad-Tags/1/Kategorie/Outdoor in der Struktur eines Cosmos-DB-Elements

Da diese Abfrage einen Gleichheitsfilter aufweist, können nach dem Durchlaufen dieser Struktur die Indexseiten, die die Abfrageergebnisse enthalten, schnell ermittelt werden. In diesem Fall würde das Abfragemodul Indexseiten lesen, die Element 00000000-0000-0000-0000-000000004368enthalten. Eine Indexsuche ist die effizienteste Möglichkeit zur Verwendung des Indexes. Bei einer Indexsuche werden nur die erforderlichen Indexseiten gelesen und nur die Elemente in den Abfrageergebnissen geladen. Daher sind der Zeitaufwand und die RU-Gebühr für die Indexsuche äußerst niedrig und zwar unabhängig vom Gesamtdatenvolumen.

Präziser Indexscan

Betrachten Sie die folgende Abfrage:

SELECT
  *
FROM
  product
WHERE
  product.inventory.quantity > 30

Das Abfrage-Prädikat (Filtern nach Elementen, bei denen mehr als 30 Einheiten im Bestand vorhanden sind) kann mit einem genauen Indexscan des inventory/quantity Pfads ausgewertet werden. Bei einem präzisen Indexscan führt die Abfrage-Engine zuerst eine Binärsuche nach dem eindeutigen Satz möglicher Werte durch, um den Speicherort des Werts 30 für den Pfad inventory/quantity zu finden. Da die Werte für jeden Pfad in aufsteigender Reihenfolge sortiert sind, kann die Abfrage-Engine ganz einfach eine Binärsuche durchführen. Nachdem die Abfrage-Engine den Wert 30 gefunden hat, beginnt sie mit dem Lesen aller verbleibenden Indexseiten (in aufsteigender Reihenfolge).

Da die Abfrage-Engine eine Binärsuche durchführen kann, um das Überprüfen unnötiger Indexseiten zu vermeiden, weisen präzise Indexscans in der Regel eine vergleichbare Latenz und ähnliche RU-Gebühren wie Indexsuchvorgänge auf.

Erweiterter Indexscan

Betrachten Sie die folgende Abfrage:

SELECT
  *
FROM
  product
WHERE
  STARTSWITH(product.inventory.warehouse, "Sea", true)

Das Abfrage-Prädikat (Filtern nach Elementen, die in einem Lager enthalten sind, dessen Name ohne Berücksichtigung der Groß-/Kleinschreibung mit "Sea" beginnt) kann mit einem erweiterten Indexscan des inventory/warehouse-Pfads ausgewertet werden. Vorgänge, die einen erweiterten Indexscan durchführen, verfügen über Optimierungen, mit denen vermieden werden kann, dass jede Indexseite überprüft werden muss, doch sind sie etwas teurer als die Binärsuche bei einem präzisen Indexscan.

Wenn z. B. StartsWith ohne Beachtung der Groß-/Kleinschreibung ausgewertet wird, überprüft die Abfrage-Engine den Index auf verschiedene mögliche Kombinationen aus Groß- und Kleinbuchstaben. Durch diese Optimierung kann die Abfrage-Engine das Lesen der meisten Indexseiten vermeiden. Verschiedene Systemfunktionen weisen unterschiedliche Optimierungen auf, mit denen das Lesen jeder Indexseite vermieden werden kann. Daher werden diese im Allgemeinen als erweiterter Indexscan kategorisiert.

Vollständiger Indexscan

Betrachten Sie die folgende Abfrage:

SELECT
  *
FROM
  product
WHERE
  CONTAINS(product.inventory.warehouse, "eat")

Das Abfrage-Prädikat (Filtern von Elementen, die über einen Lagerbestand in einem Lager verfügen, das "eat" enthält) kann mit einem Indexscan des inventory/warehouse Pfads ausgewertet werden. Im Gegensatz zu einem präzisen Indexscan wird bei einem vollständigen Indexscan immer der eindeutige Satz möglicher Werte überprüft, um die Indexseiten zu ermitteln, die Ergebnisse enthalten. In diesem Fall wird CONTAINS für den Index ausgeführt. Die Suchzeit für Indexe und die RU-Gebühr für Indexscans steigen, wenn die Kardinalität des Pfads zunimmt. Anders ausgedrückt: Je mehr mögliche eindeutige Werte von der Abfrage-Engine überprüft werden müssen, desto höher sind Latenz und RU-Gebühr für einen vollständigen Indexscan.

Sehen Sie sich beispielsweise die beiden Eigenschaften name und warehouse an. Die Kardinalität des Namens ist 5.000 und die Kardinalität von warehouse 200. Hier sind zwei Beispielabfragen, die jeweils über eine CONTAINS Systemfunktion verfügen, die einen vollständigen Indexscan für die name Eigenschaft durchführt. Die erste Abfrage verwendet mehr Anforderungseinheiten (RUs) als die zweite Abfrage, da die Kardinalität des Namens höher ist als warehouse.

SELECT
  *
FROM
  container c
WHERE
 CONTAINS(c.name, "Pack", false)
SELECT
  *
FROM
  c
WHERE
  CONTAINS(c.inventory.warehouse, "Sea", false)

Vollständiger Scan

In einigen Fällen kann das Abfragemodul möglicherweise keinen Abfragefilter mithilfe des Indexes auswerten. In diesem Fall muss die Abfrage-Engine alle Elemente aus dem Transaktionsspeicher laden, um den Abfragefilter auszuwerten. Vollständige Scans verwenden nicht den Index und haben eine RU-Gebühr, die linear mit der Gesamtdatengröße zunimmt. Glücklicherweise sind Operationen, die vollständige Überprüfungen erfordern, selten erforderlich.

Vektorsuchabfragen ohne definierten Vektorindex

Wenn Sie keine Vektorindexrichtlinie definieren und die VECTORDISTANCE Systemfunktion in einer ORDER BY Klausel verwenden, führt diese Abfrage zu einer vollständigen Überprüfung und hat eine RU-Belastung höher, als wenn Sie eine Vektorindexrichtlinie definiert haben. Ähnlichkeit, wenn Sie VECTORDISTANCE den booleschen Brute-Force-Wert auf "true" festlegen und keinen Index für den Vektorpfad definiert haben flat , tritt ein vollständiger Scan auf.

Abfragen mit komplexen Filterausdrücken

In den vorherigen Beispielen wurden nur Abfragen mit einfachen Filterausdrücken berücksichtigt (z. B. Abfragen mit nur einem Gleichheits- oder Bereichsfilter). In Wirklichkeit weisen die meisten Abfragen wesentlich komplexere Filterausdrücke auf.

Betrachten Sie die folgende Abfrage:

SELECT
  *
FROM
  product
WHERE
  product.inventory.quantity = 50 AND CONTAINS(product.inventory.warehouse, "Sea")

Zum Ausführen dieser Abfrage muss die Abfrage-Engine eine genaue Indexsuche für inventory/quantity und einen vollständigen Indexscan für inventory/warehouse ausführen. Die Abfrage-Engine weist eine interne Heuristik auf, die für eine möglichst effiziente Auswertung des Abfragefilterausdrucks genutzt wird. In diesem Fall würde die Abfrage-Engine das Lesen unnötiger Indexseiten vermeiden, indem zuerst eine Indexsuche ausgeführt wird. Wenn beispielsweise nur 50 Elemente dem Gleichheitsfilter entsprechen, muss die Abfrage-Engine nur CONTAINS auf den Indexseiten auswerten, die diese 50 Elemente enthalten. Ein vollständiger Indexscan des gesamten Containers wäre nicht erforderlich.

Indexnutzung für skalare Aggregatfunktionen

Abfragen mit Aggregatfunktionen müssen ausschließlich auf dem Index basieren, um diesen zu verwenden.

In einigen Fällen kann der Index falsch positive Ergebnisse zurückgeben. Wenn Sie beispielsweise den Index auswerten CONTAINS , kann die Anzahl der Übereinstimmungen im Index die Anzahl der Abfrageergebnisse überschreiten. Die Abfrage-Engine lädt dann alle Indexergebnisse, wertet den Filter für die geladenen Elemente aus und gibt nur die richtigen Ergebnisse zurück.

Bei den meisten Abfragen hat das Laden falsch positiver Indexergebnisse keine spürbaren Auswirkungen auf die Indexauslastung.

Betrachten Sie beispielsweise die folgende Abfrage:

SELECT
  *
FROM
  product
WHERE
  CONTAINS(product.inventory.warehouse, "Sea")

Die CONTAINS Systemfunktion gibt möglicherweise einige falsch positive Übereinstimmungen zurück, sodass das Abfragemodul überprüfen muss, ob jedes geladene Element dem Filterausdruck entspricht. In diesem Beispiel muss das Abfragemodul möglicherweise nur einige zusätzliche Elemente laden, sodass der Effekt auf die Indexauslastung und die RU-Belastung minimal ist.

Abfragen mit Aggregatfunktionen müssen jedoch ausschließlich auf dem Index basieren, um diesen zu verwenden. Betrachten Sie beispielsweise die folgende Abfrage mit einem COUNT-Aggregat:

SELECT
  COUNT(1)
FROM
  product
WHERE
  CONTAINS(product.inventory.warehouse, "Sea")

Wie im ersten Beispiel gibt die CONTAINS Systemfunktion möglicherweise einige falsch positive Übereinstimmungen zurück. Im Gegensatz zur SELECT *-Abfrage kann die COUNT-Abfrage jedoch nicht den Filterausdruck für die geladenen Elemente auswerten, um alle Indexergebnisse zu überprüfen. Die COUNT-Abfrage muss ausschließlich auf dem Index basieren. Wenn also die Möglichkeit besteht, dass ein Filterausdruck falsch positive Übereinstimmungen zurückgibt, greift die Abfrage-Engine auf eine vollständige Überprüfung zurück.

Abfragen mit den folgenden Aggregatfunktionen müssen ausschließlich auf dem Index basieren, sodass die Auswertung einiger Systemfunktionen eine vollständige Überprüfung erfordert.