Auf dieser Seite werden Konzepte beschrieben, die bei der Auswahl von Firestore-Indexen im Datastore-Modus für Ihre Anwendung zu berücksichtigen sind.
Firestore im Datastore-Modus verwendet für alle Abfragen Indexe und bietet dadurch eine hohe Abfrageleistung. Die Leistung für die meisten Abfragen hängt von der Größe der Ergebnismenge und nicht von der Gesamtgröße der Datenbank ab.
Firestore im Datastore-Modus definiert integrierte Indexe für jedes Attribut in einer Entität. Diese Indexe mit einzelnen Attributen unterstützen eine große Anzahl einfacher Abfragen. Firestore im Datastore-Modus arbeitet mit einem Feature zur Indexzusammenführung, mit dem integrierte Indexe in Ihrer Datenbank zusammengeführt werden können. Hierdurch werden zusätzliche Abfragen möglich. Bei komplexeren Abfragen müssen Sie zusammengesetzte Indexe im Voraus definieren.
Auf dieser Seite wird das Feature zur Indexzusammenführung beschrieben, da es zwei wichtige Möglichkeiten zur Indexoptimierung bietet:
- Beschleunigen von Abfragen
- Reduzieren der Anzahl zusammengesetzter Indexe
Das folgende Beispiel zeigt das praktische Funktionieren der Indexzusammenführungsfunktion.
Photo
-Entitäten filtern
Betrachten Sie eine Datenbank im Datastore-Modus mit Entitäten der Art Photo
:
Foto | ||
---|---|---|
Attribut | Werttyp | Beschreibung |
owner_id |
String | Nutzer-ID |
tag |
Stringarray | Tokenisierte Keywords |
size |
Ganzzahl |
Enumeration:
|
coloration |
Ganzzahl |
Enumeration:
|
Angenommen, Sie benötigen ein Anwendungsfeature, mit dem Nutzer Photo
-Entitäten anhand eines logischen AND
der folgenden Elemente abfragen können:
Verfügbar sind bis zu drei Filter entsprechend den Attributen:
owner_id
size
coloration
Sie verwenden einen
tag
-Suchstring. Die Anwendung tokenisiert den Suchstring in Tags und fügt für jedes Tag einen Filter hinzu.Die Anwendung wandelt beispielsweise den Suchstring
outside, family
in die Abfragefiltertag=outside
undtag=family
um.
Mithilfe der integrierten Indexe und des Indexzusammenführungs-Features von Firestore im Datastore-Modus können Sie die Indexanforderungen dieser Photo
-Filterfunktion erfüllen, ohne zusätzliche zusammengesetzte Indexe hinzufügen zu müssen.
Die integrierten Indexe für Photo
-Entitäten unterstützen Abfragen mit einzelnem Filter wie z. B.:
Python
Die Photo
-Filterfunktion erfordert auch Abfragen, die mehrere Gleichheitsfilter mit einem logischen AND
kombinieren:
Python
Der Firestore in Datastore-Modus kann diese Abfragen unterstützen, indem er integrierte Indizes zusammenführt.
Indexzusammenführung
Firestore im Datastore-Modus kann die Indexzusammenführung verwenden, wenn Ihre Abfrage und Ihre Indexe alle die folgenden Einschränkungen erfüllen:
- Die Abfrage verwendet nur Gleichheitsfilter (
=
) - Es gibt keinen zusammengesetzten Index, der perfekt mit den Filtern und der Sortierung der Abfrage übereinstimmt
- Jeder Gleichheitsfilter führt mindestens einen vorhandenen Index mit derselben Sortierung wie die Abfrage zusammen
In diesem Fall kann Firestore im Datastore-Modus mit vorhandenen Indexen die Abfrage unterstützen, anstatt einen zusätzlichen zusammengesetzten Index konfigurieren zu müssen.
Wenn zwei oder mehr Indexe nach denselben Kriterien sortiert sind, kann Firestore im Datastore-Modus die Ergebnisse mehrerer Indexscans zusammenführen, um die Ergebnisse zu finden, die allen solchen Indexen gemeinsam sind. Firestore im Datastore-Modus kann integrierte Indexe zusammenführen, da alle Werte nach Entitätsschlüssel sortiert werden.
Durch das Zusammenführen integrierter Indexe unterstützt Firestore im Datastore-Modus Abfragen mit Gleichheitsfiltern für mehrere Attribute:
Python
Firestore im Datastore-Modus kann auch Indexergebnisse aus mehreren Bereichen desselben Indexes zusammenführen. Durch Zusammenführen verschiedener Bereiche des integrierten Index für das tag
-Attribut unterstützt Firestore im Datastore-Modus Abfragen, bei denen mehrere tag
-Filter in einem logischen AND
kombiniert werden:
Python
Die Abfragen, die von zusammengeführten integrierten Indexen unterstützt werden, vervollständigen die für die Filterfunktion Photo
erforderlichen Abfragen. Beachten Sie, dass für die Unterstützung der Filterfunktion Photo
keine zusätzlichen zusammengesetzten Indexe erforderlich sind.
Bei der Auswahl der optimalen Indexe für Ihre Anwendung ist es wichtig, das Indexzusammenführungs-Feature zu verstehen. Durch das Zusammenführen von Indexen ist Firestore im Datastore-Modus flexibler bei Abfragen, die Leistung kann aber möglicherweise beeinträchtigt sein. Im nächsten Abschnitt wird die Leistung bei der Indexzusammenführung und die Leistungsverbesserung durch Hinzufügen zusammengesetzter Indexe beschrieben.
Den perfekten Index finden
Der Index wird in der per Indexdefinition vorgegebenen Reihenfolge zuerst nach Ancestor und dann nach Attributwert sortiert. Der perfekte zusammengesetzte Index für eine Abfrage, der die effizienteste Verarbeitung ermöglicht, ist nach folgenden Attributen in der angegebenen Reihenfolge definiert:
- In Gleichheitsfiltern verwendete Attribute
- In Sortierreihenfolgen verwendete Attribute
- In
distinctOn
-Filtern verwendete Attribute - In Bereichs- und Ungleichheitsfiltern verwendete Attribute, die nicht bereits in Sortierfolgen enthalten sind
- In Aggregationen und Projections verwendete Attribute, die nicht bereits in Sortierfolgen und Bereichs- und Ungleichheitsfiltern enthalten sind
Dadurch wird sichergestellt, dass alle Ergebnisse für jede mögliche Ausführung der Abfrage berücksichtigt werden. Bei Firestore-Datenbanken im Datastore-Modus werden Abfragen mit einem perfekten Index in folgenden Schritten ausgeführt:
- Identifizierung des entsprechenden Indexes für den Typ sowie die Filterattribute, Filteroperatoren und Sortierreihenfolgen der Anfrage
- Scan des Indexes vom Anfang bis zur ersten Entität, die allen oder einem Teil der Filterbedingungen der Abfrage entspricht
- Fortsetzen des Index-Scans und Ausgabe jeder Entität, die alle Filterbedingungen erfüllt, bis
- Cloud Datastore auf eine Entität trifft, die den Filterbedingungen nicht entspricht, oder
- das Index-Ende erreicht ist oder
- die maximale Anzahl von Ergebnissen, die von der Abfrage angefordert wurden, erreicht ist.
Betrachten Sie beispielsweise die folgende Abfrage:
SELECT * FROM Task
WHERE category = 'Personal'
AND priority < 3
ORDER BY priority DESC
Der perfekte zusammengesetzte Index für diese Abfrage ist ein Index von Schlüsseln für Entitäten vom Typ Task
mit Spalten für die Werte der Attribute category
und priority
. Der Index wird zuerst in aufsteigender Reihenfolge nach category
und dann in absteigender Reihenfolge nach priority
sortiert:
indexes:
- kind: Task
properties:
- name: category
direction: asc
- name: priority
direction: desc
Zwei Abfragen der gleichen Form, aber mit verschiedenen Filterwerten verwenden denselben Index. Die folgende Abfrage verwendet beispielsweise denselben Index wie die vorherige Abfrage:
SELECT * FROM Task
WHERE category = 'Work'
AND priority < 5
ORDER BY priority DESC
Für diesen Index
indexes:
- kind: Task
properties:
- name: category
direction: asc
- name: priority
direction: asc
- name: created
direction: asc
Der vorherige Index kann für beide der folgenden Abfragen verwendet werden:
SELECT * FROM Task
WHERE category = 'Personal'
AND priority = 5
ORDER BY created ASC
und
SELECT * FROM Task
WHERE category = 'Work'
ORDER BY priority ASC, created ASC
Indexauswahl optimieren
In diesem Abschnitt werden die Leistungsmerkmale der Indexzusammenführung und zwei Optimierungsmöglichkeiten im Zusammenhang mit der Indexzusammenführung beschrieben:
- Fügen Sie zusammengesetzte Indexe hinzu, um Abfragen zu beschleunigen, die auf zusammengeführten Indexen basieren
- Anzahl der zusammengesetzten Indexe reduzieren, indem Sie zusammengeführte Indexe nutzen
Leistung bei Indexzusammenführung
Bei einer Indexzusammenführung erreicht Firestore im Datastore-Modus zusätzliche Effizienz mit einem Zig-Zag-Merge-Join-Algorithmus. Mithilfe dieses Algorithmus verbindet der Datastore-Modus potenzielle Übereinstimmungen aus mehreren Indexscans, um eine Ergebnismenge passend zu einer Abfrage zu erzeugen. Ein weiteres Merkmal der Indexzusammenführung ist, dass Filterkomponenten zur Lesezeit anstatt zur Schreibzeit kombiniert werden. Deshalb hängt die Leistung – im Gegensatz zu den meisten Firestore-Abfragen im Datastore-Modus, bei denen die Leistung nur von der Größe der Ergebnismenge bestimmt wird – bei Abfragen mit Indexzusammenführung von den Filtern in der Abfrage und von der Anzahl der berücksichtigten potenziellen Übereinstimmungen ab.
Die Leistung einer Indexzusammenführung ist am besten, wenn jede potenzielle Übereinstimmung in einem Index die Abfragefilter erfüllt. In diesem Fall beträgt die Leistung O(R * I)
, wobei R
die Größe der Ergebnismenge und I
die Anzahl der gescannten Indexe ist.
Die Leistung ist am geringsten, wenn die Datenbank viele potenzielle Übereinstimmungen berücksichtigen muss, aber nur wenige davon die Abfragefilter erfüllen. In diesem Fall beträgt die Leistung O(S)
, wobei S
die Größe des kleinsten Satzes potenzieller Entitäten aus einem einzelnen Indexscan ist.
Die tatsächliche Leistung hängt von der Form der Daten ab. Die durchschnittliche Anzahl der Entitäten, die für jedes zurückgegebene Ergebnis berücksichtigt werden, beträgt O(S/(R * I))
. Die Abfragequalität verschlechtert sich, wenn viele Entitäten mit jedem Indexscan übereinstimmen, aber nur wenige Entitäten mit der Abfrage als Ganzes übereinstimmen, d. h. wenn R
klein und S
groß ist.
So können Sie jedoch das Risiko minimieren:
Der Abfrageplaner sucht eine Entität erst, wenn die Entität mit der gesamten Abfrage übereinstimmt.
Der Zig-Zag-Algorithmus muss nicht alle Ergebnisse finden, um das jeweils nächste Ergebnis zurückzugeben. Wenn Sie die ersten zehn Ergebnisse anfordern, bezahlen Sie nur für die Latenz, die durch die Ergebnissuche verursacht wird.
Der Zig-Zag-Algorithmus überspringt große Teile falsch positiver Ergebnisse. Die Leistung ist nur gering, wenn falsch positive Ergebnisse zwischen den Scans in der Sortierreihenfolge komplett verflochten sind (in Sortierreihenfolge).
Die Latenz hängt von der Anzahl der Entitäten ab, die in den einzelnen Indexscans gefunden werden, und nicht von der Anzahl der Entitäten, die mit dem jeweiligen Filter übereinstimmen. Wie im nächsten Abschnitt gezeigt, können Sie zusammengesetzte Indexe hinzufügen, um die Leistung der Indexzusammenführung zu verbessern.
Abfrage für Indexzusammenführung beschleunigen
Wenn Firestore im Datastore-Modus Indexe zusammenführt, wird jeder Indexscan häufig einem einzelnen Filter in der Abfrage zugeordnet. Sie können die Abfrageleistung verbessern, indem Sie zusammengesetzte Indexe hinzufügen, die mit mehreren Filtern in der Abfrage übereinstimmen.
Sehen Sie sich diese Abfrage an:
Python
Jeder Filter wird einem Indexscan in den folgenden integrierten Indexen zugeordnet:
Index(Photo, owner_id) Index(Photo, size) Index(Photo, tag)
Wenn Sie den zusammengesetzten Index Index(Photo, owner_id, size)
hinzufügen, wird die Abfrage zwei statt drei Indexscans zugeordnet:
# Satisfies both 'owner_id=username' and 'size=2'
Index(Photo, owner_id, size)
Index(Photo, tag)
Stellen Sie sich ein Szenario mit vielen großen Bildern vor, unter denen viele schwarz-weiße, aber wenige große Panoramabilder sind. Eine Abfragefilterung nach sowohl Panorama- als auch Schwarz-Weiß-Bildern wäre dann langsam, wenn die integrierten Indexe zusammengeführt werden:
Python
Zur Verbesserung der Abfrageleistung können Sie den Wert von S
(kleinster Satz von Entitäten in einem einzelnen Indexscan) auf O(S/(R * I))
senken. Fügen Sie hierfür den folgenden zusammengesetzten Index hinzu:
Index(Photo, size, coloration)
Im Vergleich zur Verwendung von zwei integrierten Indexen erzeugt dieser zusammengesetzte Index weniger potenzielle Ergebnisse für dieselben zwei Abfragefilter. Dieser Ansatz verbessert die Leistung erheblich, wenn auf einen zweiten Index verzichtet wird.
Anzahl der zusammengesetzten Indexe mit Indexzusammenführung reduzieren
Obwohl zusammengesetzte Indexe, die genau mit den Filtern in einer Abfrage übereinstimmen, die beste Leistung erbringen, ist es nicht immer am besten oder möglich, einen zusammengesetzten Index für jede Filterkombination hinzuzufügen. Sie müssen Ihre zusammengesetzten Indexe gegen Folgendes abwägen:
Zusammengesetzte Indexlimits:
Limit Betrag Maximale Anzahl zusammengesetzter Indexe für eine Datenbank -
200, wenn Sie die Abrechnung für Ihr Google Cloud-Projekt nicht aktiviert haben.
Wenn Sie ein darüber hinausgehendes Kontingent benötigen, müssen Sie für Ihr Projekt die Abrechnung aktivieren.
-
500 GB, wenn Sie die Abrechnung für Ihr Google Cloud-Projekt aktivieren.
Sie können den Support kontaktieren, um eine Erhöhung dieses Limits zu beantragen.
Maximale Summe der Größe von zusammengesetzten Indexeinträgen einer Entität 2 MiB Maximale Summe der folgenden Elemente für eine Entität: - Anzahl von indexierten Attributwerten
- Anzahl von zusammengesetzten Indexeinträgen
20.000 -
- Speicherkosten für jeden zusätzlichen Index
- Auswirkungen auf die Schreiblatenz.
Indexierungsprobleme treten häufig bei Feldern mit mehreren Werten wie dem tag
-Attribut der Photo
-Entitäten auf.
Angenommen, die Filterfunktion Photo
muss absteigende Sortierklauseln anhand von vier zusätzlichen Attributen unterstützen:
Foto | ||
---|---|---|
Attribut | Werttyp | Beschreibung |
date_added |
Ganzzahl | Datum/Uhrzeit |
rating |
Fließkommazahl | Gesamtbewertung des Nutzers |
comment_count |
Ganzzahl | Anzahl der Kommentare |
download_count |
Ganzzahl | Anzahl der Downloads |
Wenn Sie das Feld tag
ignorieren, ist es möglich, zusammengesetzte Indexe auszuwählen, die mit jeder Kombination von Photo
-Filtern übereinstimmen:
Index(Photo, owner_id, -date_added) Index(Photo, owner_id, -comments) Index(Photo, size, -date_added) Index(Photo, size, -comments) ... Index(Photo, owner_id, size, -date_added) Index(Photo, owner_id, size, -comments) ... Index(Photo, owner_id, size, coloration, -date_added) Index(Photo, owner_id, size, coloration, -comments)
Die Gesamtzahl der zusammengesetzten Indexe ist:
2^(number of filters) * (number of different orders) = 2 ^ 3 * 4 = 32 composite indexes
Wenn Sie versuchen, bis zu drei tag
-Filter zu unterstützen, ist die Gesamtzahl der zusammengesetzten Indexe:
2 ^ (3 + 3 tag filters) * 4 = 256 indexes.
Indexe, die Attribute mit mehreren Werten wie tag
enthalten, führen außerdem zu Problemen mit explodierenden Indexen, die die Speicherkosten und die Schreiblatenz erhöhen.
Zur Unterstützung von Filtern im Feld tag
für dieses Feature können Sie die Gesamtzahl der Indexe durch zusammengeführte Indexe reduzieren. Der folgende Satz zusammengesetzter Indexe ist das Minimum, das erforderlich ist, um die Filterfunktion Photo
mit Sortierung zu unterstützen:
Index(Photo, owner_id, -date_added) Index(Photo, owner_id, -rating) Index(Photo, owner_id, -comments) Index(Photo, owner_id, -downloads) Index(Photo, size, -date_added) Index(Photo, size, -rating) Index(Photo, size, -comments) Index(Photo, size, -downloads) ... Index(Photo, tag, -date_added) Index(Photo, tag, -rating) Index(Photo, tag, -comments) Index(Photo, tag, -downloads)
Die Anzahl der definierten zusammengesetzten Indexe ist:
(number of filters + 1) * (number of orders) = 7 * 4 = 28
Die Indexzusammenführung bietet außerdem folgende Vorteile:
- Sie ermöglicht einer
Photo
-Entität die Unterstützung von bis zu 1.000 Tags ohne Begrenzung der Anzahl dertag
-Filter pro Abfrage. - Sie reduziert die Gesamtzahl der Indexe, wodurch die Speicherkosten und die Schreiblatenz sinken.
Indexe für Ihre Anwendung auswählen
Sie können optimale Indexe für Ihre Datenbank im Datastore-Modus auswählen. Dafür gibt es zwei Ansätze:
Verwenden Sie die Indexzusammenführung, um zusätzliche Abfragen zu unterstützen
- Erfordert weniger zusammengesetzte Indexe
- Reduziert die Speicherkosten pro Entität
- Verbessert die Schreiblatenz
- Vermeidet explodierende Indexe
- Die Leistung hängt von der Form der Daten ab
Definieren Sie einen zusammengesetzten Index, der mit mehreren Filtern in einer Abfrage übereinstimmt
- Verbessert die Abfrageleistung
- Gleichbleibende Abfrageleistung, die nicht von der Form der Daten abhängt
- Darf das Limit für zusammengesetzte Indexe nicht überschreiten
- Erhöhte Speicherkosten pro Entität
- Erhöhte Schreiblatenz
Die optimalen Indexe für Ihre Anwendung hängen von der Form Ihrer Daten ab. Wenn Sie die Abfrageleistung erst einmal mit Stichproben testen, bekommen Sie eine Vorstellung davon, welche Art von Abfragen bei Ihrer Anwendung häufig vorkommt und welche Abfragen langsam sind. Entsprechend den Ergebnissen Ihrer Stichproben können Sie Indexe hinzufügen, um die Leistung derjenigen Anfragen zu verbessern, die sowohl häufig vorkommen als auch langsam sind.