Ich erwarte viel schnellere Ergebnisse mit diesem Ansatz:
1.
Erstellen Sie einen GiST-Index mit 1 Spalte, die verkettete Werte enthält:
CREATE INDEX users_search_idx ON auth_user
USING gist((username || ' ' || first_name || ' ' || last_name) gist_trgm_ops);
Dies setzt voraus, dass alle 3 Spalten definiert sind NOT NULL
(Sie haben nicht angegeben). Andernfalls müssen Sie mehr tun.
Warum nicht mit concat_ws()
vereinfachen ?
- Kombinieren Sie zwei Spalten und fügen Sie sie zu einer neuen Spalte hinzu
- Schnellere Abfrage mit Mustervergleich für mehrere Textfelder
- Kombinieren Sie zwei Spalten und fügen Sie sie zu einer neuen Spalte hinzu
2.
Verwenden Sie einen geeigneten nächster-nachbar Abfrage, passend zum obigen Index:
SELECT username, email, first_name, last_name
, similarity(username , $1) AS s_username
, similarity(first_name, $1) AS s_first_name
, similarity(last_name , $1) AS s_last_name
, row_number() OVER () AS rank -- greatest similarity first
FROM auth_user
WHERE (username || ' ' || first_name || ' ' || last_name) % $1 -- !!
ORDER BY (username || ' ' || first_name || ' ' || last_name) <-> $1 -- !!
LIMIT $2;
Ausdrücke in WHERE
und ORDER BY
muss Indexausdruck entsprechen!
Insbesondere ORDER BY rank
(wie Sie es hatten) wird für ein kleines LIMIT
immer schlecht funktionieren Auswahl aus einem viel größeren Pool qualifizierter Zeilen, da ein Index nicht direkt verwendet werden kann:Der ausgeklügelte Ausdruck hinter rank
muss für jeden berechnet werden Qualifikationsreihe, dann müssen alle sortiert werden, bevor die kleine Auswahl der besten Übereinstimmungen zurückgegeben werden kann. Das ist viel, viel teurer als eine echte Nächster-Nachbar-Abfrage, die direkt die besten Ergebnisse aus dem Index auswählen kann, ohne sich den Rest auch nur anzusehen.
row_number()
mit leerer Fensterdefinition spiegelt nur die Reihenfolge wider, die durch ORDER BY
erzeugt wird desselben SELECT
.
Verwandte Antworten:
Wie für Ihren Artikel 3.
, ich habe eine Antwort auf die Frage hinzugefügt, auf die Sie verwiesen haben, die es erklären sollte: