Očekávám hodně rychlejší výsledky s tímto přístupem:
1.
Vytvořte index GiST s 1 sloupcem obsahujícím zřetězené hodnoty:
CREATE INDEX users_search_idx ON auth_user
USING gist((username || ' ' || first_name || ' ' || last_name) gist_trgm_ops);
To předpokládá, že všechny 3 sloupce budou definovány NOT NULL
(neuvedl jste). Jinak musíte udělat víc.
Proč nezjednodušit pomocí concat_ws()
?
- Spojte dva sloupce a přidejte je do jednoho nového sloupce
- Rychlejší dotaz s párováním vzorů ve více textových polích
- Spojte dva sloupce a přidejte je do jednoho nového sloupce
2.
Použijte správný nejbližšího souseda dotaz odpovídající výše uvedenému indexu:
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;
Výrazy v WHERE
a ORDER BY
musí odpovídat výrazu indexu!
Zejména ORDER BY rank
(jako byste to měli vy) bude vždy fungovat špatně za malý LIMIT
výběr z mnohem většího fondu kvalifikačních řádků, protože nemůže přímo použít index:sofistikovaný výraz za rank
se musí počítat pro každý kvalifikační řadě, pak musí být všechny seřazeny, než bude možné vrátit malý výběr nejlepších zápasů. To jemnohem, mnohem dražší než skutečný dotaz na nejbližšího souseda, který dokáže vybrat nejlepší výsledky z indexu přímo, aniž by se musel dívat na zbytek.
row_number()
s definicí prázdného okna pouze odráží řazení vytvořené ORDER BY
stejného SELECT
.
Související odpovědi:
Pokud jde o vaši položku 3.
, přidal jsem odpověď na otázku, na kterou jste odkazoval, která by to měla vysvětlit: