View a markdown version of this page

Index-only Scans (abgedeckte Abfragen) - Amazon DocumentDB

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Index-only Scans (abgedeckte Abfragen)

Ein reiner Index-Scan (auch als abgedeckte Abfrage bezeichnet) ist eine Optimierung, bei der Amazon DocumentDB eine Abfrage ausschließlich anhand der in einem Index gespeicherten Felder beantwortet, ohne die zugrunde liegenden Dokumente zu lesen. Da die Werte, die eine Abfrage benötigt, bereits im Index vorhanden sind, kann Amazon DocumentDB das Abrufen jedes passenden Dokuments überspringen, wodurch die zufälligen I/O und dekodierenden Kosten für das Lesen vollständiger Dokumente vermieden werden. Im Abfrageplan wird ein reiner Index-Scan als IXONLYSCAN Phase anstelle eines IXSCAN (Index-Scans) oder COLLSCAN (Sammlungsscans) angezeigt. Dadurch wird die Abfragelatenz für unterstützte Abfragen reduziert I/O und kann diese erheblich verringern.

Eine Abfrage eignet sich gut für einen reinen Index-Scan, wenn sie nur eine kleine Anzahl von Feldern betrifft, die alle in einem einzigen Index vorhanden sind, insbesondere wenn die Dokumente selbst groß sind. Gängige Beispiele sind Dashboards, Analytics-Rollups und Lookups, bei denen einige Felder aus einem größeren zusammengesetzten Index gelesen werden.

Die Ergebnisse einer Abfrage sind dieselben, unabhängig davon, ob ein reiner Index-Scan verwendet wird oder nicht. Nur der Abfrageplan und der Umfang, in dem I/O er ausgeführt wird, ändern sich.

Anmerkung

Index-only Die Scanunterstützung hängt von Ihrer Amazon DocumentDB-Engine-Version ab:

  • Für abgedeckte find Prognosen, die mehr als ein Feld enthalten, das kein _id Feld ist, ist die Engine-Version 8.0.2 oder höher erforderlich. In früheren Versionen kann eine abgedeckte find Projektion höchstens ein Feld enthalten, das kein _id Feld ist. Eine Projektion mit zwei oder mehr Feldern fällt auf einen normalen Index- oder Sammelscan zurück.

  • Index-only Für Scans nach Aggregations-Pipelines, z. B. für Covered$group, ist die Engine-Version 8.0.2 oder höher erforderlich.

Wenn Amazon DocumentDB einen reinen Index-Scan verwendet

Amazon DocumentDB erwägt für die folgenden Operationen einen reinen Index-Scan, wenn ein einziger Index jedes Feld enthält, das der Vorgang liest.

Abgedeckt, Prognosen finden

Eine find Abfrage ist qualifiziert, wenn ihre Projektion die einfache Einbeziehung eines oder mehrerer Felder der obersten Ebene ist und jedes projizierte Feld in einem einzigen Index enthalten ist. Wenn beispielsweise ein zusammengesetzter Index aktiviert ist{ customerId: 1, status: 1, total: 1 }, wird die folgende Abfrage behandelt. Alle drei projizierten Felder befinden sich im Index und _id sind ausdrücklich ausgeschlossen. (Um eine Projektion mit mehr als einem _id Nicht-Feld abzudecken, ist Engine-Version 8.0.2 oder höher erforderlich.)

db.orders.createIndex({ customerId: 1, status: 1, total: 1 }) db.orders.find( { customerId: 42 }, { _id: 0, customerId: 1, status: 1, total: 1 } )

Der erfolgreiche Plan verwendet eine IXONLYSCAN Stufe und holt niemals die passenden Dokumente aus dem Speicher ab:

{ "stage": "IXONLYSCAN", "indexName": "customerId_1_status_1_total_1", "direction": "forward", "indexCond": { "$and": [ { "customerId": { "$eq": 42 } } ] } }
Anmerkung

In einer abgedeckten find Abfrage werden die Felder im Ergebnis in der Indexreihenfolge zurückgegeben (in der Reihenfolge, in der die Felder in der Indexdefinition erscheinen), nicht in der Reihenfolge, in der sie in der Projektion aufgeführt wurden, oder in der Reihenfolge, in der sie im Dokument gespeichert sind. Dies entspricht dem Verhalten von MongoDB für abgedeckte Abfragen. Eine Abfrage, die durch einen Sammlungsscan beantwortet wird, gibt stattdessen Felder in der Reihenfolge der gespeicherten Dokumente zurück.

Es wurden $group-Aggregationen abgedeckt

Eine $group Phase liest normalerweise nur wenige Felder (den Gruppenschlüssel und die Eingaben für ihre Akkumulatoren), wird aber oft ohne vorangestelltes Zeichen ausgeführt. $match Ohne einen übergeordneten Index liest und dekodiert Amazon DocumentDB jedes vollständige Dokument in der Sammlung, nur um diese wenigen Felder in die Gruppierung einzufügen.

Index-only Scans für Aggregationspipelines, einschließlich der abgedeckten $group Stufen, sind in der Engine-Version 8.0.2 und höher verfügbar.

Wenn ein einzelner Index jedes Feld enthält, das das Pipeline-Präfix liest, kann Amazon DocumentDB einen reinen Index-Scan unter der Gruppe platzieren und diese Felder direkt aus dem Index lesen. Stellen Sie sich eine Pipeline vor, die Bestellungen nach Status gruppiert und ihre Gesamtsummen summiert, mit einem zusammengesetzten Index für: { status: 1, total: 1 }

db.orders.createIndex({ status: 1, total: 1 }) db.orders.aggregate([ { $group: { _id: "$status", revenue: { $sum: "$total" } } } ])

Die Pipeline liest nur status und total beide sind im Index enthalten, sodass die Gruppe nicht aus einem Sammelscan, IXONLYSCAN sondern aus einem Sammelscan gescannt wird:

// Without a covering index $group <- COLLSCAN (reads and decodes every full document) // With a covering index on { status, total } $group <- IXONLYSCAN over { status, total } (reads only the referenced fields)

Ein führendes $match$sort,$skip, oder $limit vor dem $group wird unterstützt. Jedes Feld, auf das diese Stufen verweisen (z. B. ein $match Filterfeld oder ein $sort Schlüssel), muss jedoch auch im gleichen Index vorhanden sein, damit die Pipeline abgedeckt wird. Wenn ein Feld, auf das verwiesen wird, im Index fehlt, greift Amazon DocumentDB auf einen Sammlungs- oder Index-Scan zurück.

Anmerkung

Im Gegensatz zu einer find Projektion $group schließt a das Dokument nicht implizit ein. _id _idIn a $group ist der Gruppenschlüssel, nicht die Dokument-ID, sodass der Index das Dokument _id nicht enthalten muss, um die Pipeline abzudecken.

Anforderungen für eine abgedeckte Abfrage

Damit Amazon DocumentDB einen reinen Index-Scan verwenden kann, müssen alle folgenden Bedingungen erfüllt sein:

  • Ein einziger Index enthält jedes Feld, das die Abfrage liest. Dazu gehören projizierte Felder für find und den Gruppenschlüssel, Akkumulatoreingaben und alle Filter- oder Sortierfelder für eine abgedeckte $group Pipeline. Wenn auch nur ein Feld im Index fehlt, kann die Abfrage nicht abgedeckt werden.

  • Die Projektion beinhaltet Felder der obersten Ebene (fürfind). Ausschlussprognosen, berechnete Felder und Projektionsoperatoren wie $slice und $elemMatch sind nicht zulässig.

  • Das _id Feld wird berücksichtigt (fürfind). Weil standardmäßig enthalten _id ist, ist ein allgemeiner zusammengesetzter Index wie „Nicht { a: 1, b: 1 } deckt“find({}, { a: 1, b: 1 }): Das Implizite _id ist nicht im Index enthalten. Entweder _id aus der Projektion ausschließen ({ _id: 0, a: 1, b: 1 }) oder _id zum Index hinzufügen.

  • Der Filter entspricht voll und ganz dem Index. Wenn Amazon DocumentDB einen Teil des Abfrageprädikats nicht in eine Indexbindung umwandeln kann, behält es diesen Teil als Restfilter bei, liest das Dokument, um es auszuwerten, und konvertiert den Scan nicht in einen reinen Index-Scan. Operatoren wie$mod, $ne$nin, und $exists hinterlassen einen Restfilter.

  • Kein projiziertes Feld ist eine Mehrschlüsselspalte (Array). Siehe Einschränkungen.

Einschränkungen

In den folgenden Fällen kann ein reiner Index-Scan nicht verwendet werden und es wird auf einen normalen Index- oder Sammlungsscan zurückgegriffen. Dies ist ein erwartetes Verhalten und hat keinen Einfluss auf die Richtigkeit der Ergebnisse.

  • Felder mit mehreren Schlüsseln (Array). Wenn ein Feld in einem Dokument jemals einen Array-Wert enthielt, ist seine Indexspalte mit mehreren Schlüsseln versehen. Ein Mehrschlüsselindex speichert einen Eintrag pro Array-Element, sodass das ursprüngliche Array nicht aus dem Index rekonstruiert werden kann. Jede Abfrage, die ein solches Feld liest, wird nicht behandelt.

  • Gepunktete oder verschachtelte Pfade. Eine Projektion oder ein Feldreferenz auf einem verschachtelten Pfad wie "address.city" ist nicht zulässig, auch wenn der Index diesen Pfad enthält.

  • Ausschluss-, berechnete oder Operatorprojektionen. Prognosen wie{ b: 0 },{ total: { $add: ["$price", "$tax"] } }, oder { a: { $slice: 5 } } erfordern das vollständige Dokument und werden nicht behandelt.

  • Whole-document Referenzen in Aggregation. Ein Dokument$group, das auf das gesamte Dokument verweist (z. B.{ $push: "$$ROOT" }), kann nicht abgedeckt werden, da kein Index das gesamte Dokument rekonstruieren kann.

  • Vorangegangene Etappen umgestalten. $group Eine Phase, in der Dokumente (wie$project,, oder$lookup)$addFields, die vor dem erscheinen$unwind, neu gestaltet werden, verhindert$group, dass die Pipeline abgedeckt wird.

  • Die Sortierung stimmt bei Zeichenkettenprädikaten nicht überein. Wenn sich die Sortierung der Abfrage von der Sortierung des Indexes unterscheidet, können Zeichenkettenprädikate nicht vom Index bereitgestellt werden und hinterlassen einen Restfilter, der einen Dokumentabruf erzwingt. Numerische und typbasierte Prädikate sind davon nicht betroffen.

Bestätigung eines reinen Index-Scans

Bestätigen Sie anhand der explain("executionStats") Ausgabe, ob eine Abfrage nur durch einen Indexscan bearbeitet wird und dass Dokumente nicht betroffen sind. Achten Sie auf zwei Dinge:

  • Der Gewinnplan nutzt die IXONLYSCAN Bühne.

  • Der docsExamined Wert in dieser Phase ist 0 (und totalDocsExamined ist0), was bedeutet, dass die Abfrage vollständig aus dem Index heraus beantwortet wurde, ohne dass Dokumente gelesen wurden.

db.orders.find( { customerId: 42 }, { _id: 0, customerId: 1, status: 1, total: 1 } ).explain("executionStats").executionStats
{ "executionSuccess": true, "nReturned": "2", "executionTimeMillis": "0.714", "totalDocsExamined": "0", "executionStages": { "stage": "IXONLYSCAN", "nReturned": "2", "indexName": "customerId_1_status_1_total_1", "direction": "forward", "docsExamined": "0" } }
Anmerkung

Ein docsExamined Wert ungleich Null auf einer IXONLYSCAN Stufe bedeutet, dass der Index die Daten enthielt, aber Amazon DocumentDB überprüfte trotzdem den Speicher, um zu bestätigen, dass jede Dokumentversion sichtbar war. Dies kann passieren, wenn die Sammlung kürzlich Schreibvorgänge enthält, deren veraltete Dokumentversionen die Garbage Collection noch nicht abgerufen hat. Sobald die Garbage Collection diese Dokumente verarbeitet hat, docsExamined fällt sie auf. 0 An diesem Punkt realisiert die Abfrage den vollen Nutzen des abgedeckten Scans. Weitere Informationen zur Speicherbereinigung finden Sie unterMüllabfuhr in Amazon DocumentDB. Für weitere Informationen über die docsExamined-Metrik siehe Plananalyse abfragen.

Bewährte Methoden

  • Entwerfen Sie zusammengesetzte Indizes, die die Felder enthalten, nach denen Ihre häufigsten Abfragen projiziert oder gruppiert werden, sodass diese Abfragen abgedeckt werden können.

  • _idAus find Projektionen ausschließen ({ _id: 0, ... }), sofern es nicht Teil des abdeckenden Indexes _id ist.

  • Vermeiden Sie es, Array-Felder (Mehrschlüssel) zu indizieren, wenn Sie beabsichtigen, eine Abfrage abzudecken, da Mehrschlüsselspalten den reinen Indexpfad disqualifizieren.

  • Sorgen Sie dafür, dass die Garbage-Collection mit Ihrem Schreibaufwand Schritt hält, sodass abgedeckte Scans den Zugriff auf Dokumente überspringen und konstant bleiben. docsExamined 0 Weitere Informationen finden Sie unter Müllabfuhr in Amazon DocumentDB.