In diesem Dokument erfahren Sie, wie Sie Ihre Indexe optimieren, um eine schnellere Abfrageleistung und eine bessere Rückrufleistung zu erzielen.
ScaNN
-Index optimieren
Der ScaNN-Index verwendet eine Indexierung, die auf der Quantisierung von Bäumen basiert. Bei der Baumquantisierung lernen Indexe einen Suchbaum zusammen mit einer Quantisierungs- (oder Hash-) Funktion. Wenn Sie eine Abfrage ausführen, wird der Suchbaum verwendet, um den Suchraum zu beschneiden, während die Quantisierung verwendet wird, um die Indexgröße zu komprimieren. Durch diese Beschneidung wird die Bewertung der Ähnlichkeit (d.h. der Distanz) zwischen dem Abfragevektor und den Datenbankvektoren beschleunigt.
Wenn Sie sowohl eine hohe Abfragerate pro Sekunde (QPS) als auch eine hohe Trefferquote bei Abfragen nach dem nächsten Nachbarn erzielen möchten, müssen Sie den Baum Ihres ScaNN
-Index so partitionieren, dass er am besten zu Ihren Daten und Abfragen passt.
Bevor Sie einen ScaNN
-Index erstellen, müssen Sie Folgendes tun:
- Achten Sie darauf, dass bereits eine Tabelle mit Ihren Daten erstellt wurde.
- Achten Sie darauf, dass der Wert, den Sie für das
maintenance_work_mem
- und dasshared_buffers
-Flag festlegen, kleiner als der Gesamtarbeitsspeicher des Computers ist, um Probleme beim Generieren des Index zu vermeiden.
Parameter für die Abstimmung
Die folgenden Indexparameter und Datenbankflaggen werden zusammen verwendet, um das richtige Gleichgewicht zwischen Rückruf und QPS zu finden. Alle Parameter gelten für beide ScaNN
-Indextypen.
Parameter für die Abstimmung | Beschreibung | Parametertyp |
---|---|---|
num_leaves |
Die Anzahl der Partitionen, die auf diesen Index angewendet werden sollen. Die Anzahl der Partitionen, auf die Sie beim Erstellen eines Index anwenden, wirkt sich auf die Indexleistung aus. Wenn Sie die Partitionen für eine festgelegte Anzahl von Vektoren erhöhen, erstellen Sie einen detaillierteren Index, was die Abruf- und Abfrageleistung verbessert. Dies geht jedoch zu Lasten der Indexerstellungszeit. Da Drei-Ebenen-Bäume schneller erstellt werden als Zwei-Ebenen-Bäume, können Sie den Wert für num_leaves_value beim Erstellen eines Drei-Ebenen-Baumindexes erhöhen, um eine bessere Leistung zu erzielen.
|
Indexerstellung |
quantizer |
Die Art des Quantisierers, die Sie für den K-Means-Baum verwenden möchten. Der Standardwert ist SQ8 für eine bessere Abfrageleistung.Legen Sie ihn auf FLAT fest, um die Wahrscheinlichkeit zu erhöhen, dass die Daten abgerufen werden. |
Indexerstellung |
enable_pca |
Hiermit wird die Hauptkomponentenanalyse (Principal Component Analysis, PCA) aktiviert. Dabei handelt es sich um eine Dimensionsreduktionstechnik, mit der die Größe der Einbettung nach Möglichkeit automatisch verringert wird. Diese Option ist standardmäßig aktiviert. Legen Sie false fest, wenn sich die Erinnerungsfähigkeit verschlechtert. |
Indexerstellung |
scann.num_leaves_to_search |
Das Datenbankflag steuert den Kompromiss zwischen Trefferquote und QPS. Der Standardwert ist 1% des in num_leaves festgelegten Werts. Je höher der festgelegte Wert, desto besser ist der Recall, aber die QPS ist niedriger. Umgekehrt gilt das Gleiche. |
Ausführungszeit der Abfrage |
scann.max_top_neighbors_buffer_size |
Mit dem Datenbankflag wird die Größe des Caches angegeben, der verwendet wird, um die Leistung für gefilterte Abfragen zu verbessern. Dazu werden die gescannten Kandidatennachbarn im Arbeitsspeicher anstelle auf der Festplatte bewertet oder sortiert. Der Standardwert ist 20000 . Je höher der festgelegte Wert ist, desto höher ist die Anzahl der Abfragen pro Sekunde bei gefilterten Abfragen. Dies führt jedoch zu einer höheren Arbeitsspeichernutzung und umgekehrt. |
Ausführungszeit der Abfrage |
scann.pre_reordering_num_neighbors |
Wenn das Datenbankflag festgelegt ist, gibt es an, wie viele Kandidaten in den Neusortierungsphasen berücksichtigt werden sollen, nachdem bei der ersten Suche eine Reihe von Kandidaten ermittelt wurde. Legen Sie einen Wert fest, der höher ist als die Anzahl der Nachbarn, die durch die Abfrage zurückgegeben werden sollen. Größere Wertemengen führen zu einer besseren Trefferquote, aber dieser Ansatz führt zu einer geringeren QPS. |
Ausführungszeit der Abfrage |
max_num_levels |
Die maximale Anzahl von Ebenen des K-Means-Clustering-Baums.
|
Indexerstellung |
ScaNN
-Index optimieren
In den folgenden Beispielen für ScaNN
-Indexe mit zwei und drei Ebenen wird gezeigt, wie die Optimierungsparameter festgelegt werden:
Zweistufiger Index
SET LOCAL scann.num_leaves_to_search = 1;
SET LOCAL scann.pre_reordering_num_neighbors=50;
CREATE INDEX my-scann-index ON my-table
USING scann (vector_column cosine)
WITH (num_leaves = [power(1000000, 1/2)]);
Dreistufiger Index
SET LOCAL scann.num_leaves_to_search = 10;
SET LOCAL scann.pre_reordering_num_neighbors=50;
CREATE INDEX my-scann-index ON my-table
USING scann (vector_column cosine)
WITH (num_leaves = [power(1000000, 2/3)], max_num_levels = 2);
Alle Einfüge- oder Aktualisierungsvorgänge für eine Tabelle, für die bereits ein ScaNN
-Index generiert wurde, wirken sich darauf aus, wie der gelernte Baum den Index optimiert. Wenn Ihre Tabelle häufig aktualisiert oder Daten eingefügt werden, empfehlen wir, den vorhandenen ScaNN
-Index regelmäßig neu zu indexieren, um die Abrufgenauigkeit zu verbessern.
Sie können Indexmesswerte überwachen, um die Anzahl der Mutationen zu ermitteln, die seit dem Erstellen des Index erstellt wurden, und dann entsprechend neu indexieren. Weitere Informationen zu Messwerten finden Sie unter Messwerte für Vektorindexe.
Best Practices für die Optimierung
Je nachdem, welchen ScaNN
-Index Sie verwenden möchten, variieren die Empfehlungen zur Indexoptimierung. In diesem Abschnitt finden Sie Empfehlungen zur Optimierung der Indexparameter für ein optimales Gleichgewicht zwischen Rückruf und QPS.
Zweistufiger Baumindex
So wenden Sie Empfehlungen an, um die optimalen Werte für num_leaves
und num_leaves_to_search
für Ihren Datensatz zu ermitteln:
- Erstellen Sie den
ScaNN
-Index mitnum_leaves
als Quadratwurzel der Zeilenanzahl der indexierten Tabelle. - Führen Sie die Testabfragen aus und erhöhen Sie den Wert von
scann.num_of_leaves_to_search
, bis Sie den gewünschten Bereich für die Wiedererkennung erreichen, z. B. 95%. Weitere Informationen zur Analyse von Abfragen finden Sie unter Abfragen analysieren. - Notieren Sie sich das Verhältnis zwischen
scann.num_leaves_to_search
undnum_leaves
, das in den nächsten Schritten verwendet wird. Dieses Verhältnis liefert eine Näherung an den Datensatz, mit der Sie die gewünschte Wiedererkennung erzielen.
Wenn Sie mit Vektoren mit hoher Dimension (500 Dimensionen oder mehr) arbeiten und die Wiedererkennung verbessern möchten, können Sie den Wert vonscann.pre_reordering_num_neighbors
anpassen. Legen Sie als Ausgangspunkt den Wert auf100 * sqrt(K)
fest, wobeiK
das Limit ist, das Sie in Ihrer Abfrage festgelegt haben. - Wenn die QPS zu niedrig ist, nachdem Ihre Abfragen die gewünschte Trefferquote erreicht haben, gehen Sie so vor:
- Erstellen Sie den Index neu und erhöhen Sie die Werte von
num_leaves
undscann.num_leaves_to_search
gemäß der folgenden Anleitung:- Legen Sie für
num_leaves
einen größeren Faktor der Quadratwurzel der Zeilenanzahl fest. Wennnum_leaves
im Index beispielsweise auf die Quadratwurzel der Zeilenanzahl festgelegt ist, versuchen Sie, den Wert auf das Doppelte der Quadratwurzel zu setzen. Wenn der Wert bereits doppelt so hoch ist, versuchen Sie, ihn auf das Dreifache der Quadratwurzel festzulegen. - Erhöhen Sie
scann.num_leaves_to_search
nach Bedarf, um das Verhältnis zunum_leaves
beizubehalten, das Sie in Schritt 3 notiert haben. - Legen Sie für
num_leaves
einen Wert fest, der kleiner oder gleich der Anzahl der Zeilen geteilt durch 100 ist.
- Legen Sie für
- Führen Sie die Testabfragen noch einmal aus.
Versuchen Sie während der Ausführung der Testabfragen,
scann.num_leaves_to_search
zu reduzieren, um einen Wert zu finden, mit dem die Anzahl der Abfragen pro Sekunde erhöht wird, während die Trefferquote hoch bleibt. Probieren Sie verschiedene Werte fürscann.num_leaves_to_search
aus, ohne den Index neu zu erstellen.
- Erstellen Sie den Index neu und erhöhen Sie die Werte von
- Wiederholen Sie Schritt 4, bis sowohl die QPS als auch der Rückrufbereich akzeptable Werte erreicht haben.
Dreistufiger Baumindex
Zusätzlich zu den Empfehlungen für den zweistufigen BaumScaNN
-Index können Sie die folgenden Hinweise und Schritte zur Optimierung des Index verwenden:
- Wenn Sie
max_num_levels
von1
für einen zweistufigen Baum auf2
für einen dreistufigen Baum erhöhen, verkürzt sich die Zeit zum Erstellen eines Index erheblich. Dies geht jedoch zu Lasten der Recall-Genauigkeit. Legen Siemax_num_levels
mithilfe der folgenden Empfehlung fest:- Legen Sie den Wert auf
2
fest, wenn die Anzahl der Vektorzeilen 100 Millionen überschreitet. - Legen Sie den Wert auf
1
fest, wenn die Anzahl der Vektorzeilen weniger als 10 Millionen beträgt. - Legen Sie entweder
1
oder2
fest, wenn die Anzahl der Vektorzeilen zwischen 10 Millionen und 100 Millionen liegt. Berücksichtigen Sie dabei die Zeit für die Indexerstellung und die erforderliche Abrufgenauigkeit.
- Legen Sie den Wert auf
So wenden Sie Empfehlungen an, um den optimalen Wert für die Indexparameter num_leaves
und max_num_levels
zu ermitteln:
Erstellen Sie den
ScaNN
-Index mit den folgendennum_leaves
- undmax_num_levels
-Kombinationen basierend auf Ihrem Datenpool:- Vector Rows-Zeilen mit mehr als 100 Millionen Zeilen: Legen Sie
max_num_levels
als2
undnum_leaves
alspower(rows, ⅔)
fest. - Weniger als 100 Millionen Vektorzeilen: Legen Sie
max_num_levels
als1
undnum_leaves
alssqrt(rows)
fest. - Vektorzeilen zwischen 10 Millionen und 100 Millionen Zeilen: Legen Sie zuerst
max_num_levels
als1
undnum_leaves
alssqrt(rows)
fest.
- Vector Rows-Zeilen mit mehr als 100 Millionen Zeilen: Legen Sie
Führen Sie Ihre Testabfragen aus. Weitere Informationen zum Analysieren von Abfragen finden Sie unter Abfragen analysieren.
Wenn die Indexerstellungszeit zufriedenstellend ist, belassen Sie den Wert für
max_num_levels
und experimentieren Sie mit dem Wert fürnum_leaves
, um die Genauigkeit der Wiedererkennung zu optimieren.Wenn Sie mit der Zeit für die Indexerstellung nicht zufrieden sind, gehen Sie so vor:
Wenn der Wert von
max_num_levels
1
ist, löschen Sie den Index. Erstellen Sie den Index neu, wobei der Wert fürmax_num_levels
auf2
festgelegt ist.Führen Sie die Abfragen aus und optimieren Sie den Wert für
num_leaves
, um eine optimale Trefferquote zu erzielen.Wenn der Wert für
max_num_levels
2
ist, löschen Sie den Index. Erstellen Sie den Index mit demselbenmax_num_levels
-Wert neu und optimieren Sie dennum_leaves
-Wert für eine optimale Abrufgenauigkeit.
IVF
-Index optimieren
Durch die Optimierung der Werte, die Sie für die Parameter lists
, ivf.probes
und quantizer
festgelegt haben, lässt sich die Leistung Ihrer Anwendung möglicherweise optimieren:
Parameter für die Abstimmung | Beschreibung | Parametertyp |
---|---|---|
lists |
Die Anzahl der Listen, die beim Erstellen des Index erstellt wurden. Der Ausgangspunkt für die Festlegung dieses Werts ist (rows)/1000 für bis zu eine Million Zeilen und sqrt(rows) für mehr als eine Million Zeilen. |
Indexerstellung |
quantizer |
Die Art des Quantisierers, die Sie für den K-Means-Baum verwenden möchten. Der Standardwert ist SQ8 für eine bessere Abfrageleistung. Legen Sie FLAT fest, um sich besser daran zu erinnern. |
Indexerstellung |
ivf.probes |
die Anzahl der Listen, die bei der Suche angezeigt werden sollen. Der Ausgangspunkt für diesen Wert ist sqrt(lists) . |
Ausführungszeit der Abfrage |
Im folgenden Beispiel wird ein IVF
-Index mit den eingestellten Optimierungsparametern gezeigt:
SET LOCAL ivf.probes = 10;
CREATE INDEX my-ivf-index ON my-table
USING ivf (vector_column cosine)
WITH (lists = 100, quantizer = 'SQ8');
IVFFlat
-Index optimieren
Durch die Optimierung der Werte, die Sie für die Parameter lists
und ivfflat.probes
festgelegt haben, lässt sich die Anwendungsleistung verbessern:
Parameter für die Abstimmung | Beschreibung | Parametertyp |
---|---|---|
lists |
Die Anzahl der Listen, die beim Erstellen des Index erstellt wurden. Der Ausgangspunkt für die Festlegung dieses Werts ist (rows)/1000 für bis zu eine Million Zeilen und sqrt(rows) für mehr als eine Million Zeilen. |
Indexerstellung |
ivfflat.probes |
Die Anzahl der Listen, die bei der Suche untersucht werden sollen. Der Ausgangspunkt für diesen Wert ist sqrt(lists) . |
Ausführungszeit der Abfrage |
Bevor Sie einen IVFFlat
-Index erstellen, muss das IVFFlat
-Flag Ihrer Datenbank auf einen Wert festgelegt sein, der die Indexerstellung in großen Tabellen beschleunigt.max_parallel_maintenance_workers
Im folgenden Beispiel wird ein IVFFlat
-Index mit den eingestellten Optimierungsparametern gezeigt:
SET LOCAL ivfflat.probes = 10;
CREATE INDEX my-ivfflat-index ON my-table
USING ivfflat (vector_column cosine)
WITH (lists = 100);
HNSW
-Index optimieren
Durch die Optimierung der Werte, die Sie für die Parameter m
, ef_construction
und hnsw.ef_search
festgelegt haben, lässt sich die Anwendungsleistung verbessern.
Parameter für die Abstimmung | Beschreibung | Parametertyp |
---|---|---|
m |
Die maximale Anzahl von Verbindungen pro Knoten im Graphen. Sie können mit dem Standardwert 16 (Standard) beginnen und je nach Größe des Datensatzes mit höheren Werten experimentieren. |
Indexerstellung |
ef_construction |
Die Größe der dynamischen Kandidatenliste, die während der Graphenkonstruktion verwaltet wird und die aktuellen besten Kandidaten für die nächsten Nachbarn eines Knotens ständig aktualisiert. Legen Sie diesen Wert auf einen Wert fest, der mehr als doppelt so hoch wie der Wert für m ist, z. B. 64 (Standard). |
Indexerstellung |
ef_search |
Die Größe der dynamischen Kandidatenliste, die bei der Suche verwendet wird. Sie können diesen Wert entweder auf m oder ef_construction festlegen und dann ändern, während Sie den Abruf beobachten. Der Standardwert ist 40 . |
Ausführungszeit der Abfrage |
Im folgenden Beispiel wird ein hnsw
-Index mit den eingestellten Optimierungsparametern gezeigt:
SET LOCAL hnsw.ef_search = 40;
CREATE INDEX my-hnsw-index ON my-table
USING hnsw (vector_column cosine)
WITH (m = 16, ef_construction = 200);
Abfragen analysieren
Verwenden Sie den Befehl EXPLAIN ANALYZE
, um Ihre Abfragestatistiken zu analysieren, wie in der folgenden Beispiel-SQL-Abfrage gezeigt.
EXPLAIN ANALYZE SELECT result-column FROM my-table
ORDER BY EMBEDDING_COLUMN ::vector
USING INDEX my-scann-index
<-> embedding('textembedding-gecko@003', 'What is a database?')
LIMIT 1;
Die Beispielantwort QUERY PLAN
enthält Informationen wie die benötigte Zeit, die Anzahl der gescannten oder zurückgegebenen Zeilen und die verwendeten Ressourcen.
Limit (cost=0.42..15.27 rows=1 width=32) (actual time=0.106..0.132 rows=1 loops=1)
-> Index Scan using my-scann-index on my-table (cost=0.42..858027.93 rows=100000 width=32) (actual time=0.105..0.129 rows=1 loops=1)
Order By: (embedding_column <-> embedding('textgecko@003', 'What is a database?')::vector(768))
Limit value: 1
Planning Time: 0.354 ms
Execution Time: 0.141 ms
Messwerte für Vektorindexe ansehen
Mit den Messwerten für Vektorindexe können Sie die Leistung Ihres Vektorindex prüfen, Verbesserungsmöglichkeiten ermitteln und den Index bei Bedarf anhand der Messwerte optimieren.
Wenn Sie alle Messwerte für den Vektorindex aufrufen möchten, führen Sie die folgende SQL-Abfrage aus, in der die Ansicht pg_stat_ann_indexes
verwendet wird:
SELECT * FROM pg_stat_ann_indexes;
Eine vollständige Liste der Messwerte finden Sie unter Messwerte für Vektorindexe.