PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Optymalizacja zapytania dotyczącego podobieństwa postgres (pg_trgm + indeks gin)

Oczekuję dużo szybsze wyniki dzięki temu podejściu:

1.

Utwórz indeks GiST z 1 kolumną zawierającą połączone wartości:

CREATE INDEX users_search_idx ON auth_user
USING gist((username || ' ' || first_name || ' ' || last_name) gist_trgm_ops);

Zakłada się, że wszystkie 3 kolumny mają być zdefiniowane NOT NULL (nie określiłeś). W przeciwnym razie musisz zrobić więcej.
Dlaczego nie uprościć za pomocą concat_ws() ?

2.

Użyj prawidłowego zapytanie, pasujące do powyższego indeksu:

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;

Wyrażenia w WHERE i ORDER BY musi pasować do wyrażenia indeksu!

W szczególności ORDER BY rank (tak jak miałeś) zawsze będzie działać słabo dla małego LIMIT wybieranie ze znacznie większej puli kwalifikujących się wierszy, ponieważ nie może bezpośrednio używać indeksu:Wyrafinowane wyrażenie stojące za rank należy obliczyć dla każdej kwalifikacyjny wiersz, a następnie wszystkie muszą zostać posortowane, zanim będzie można zwrócić mały wybór najlepszych meczów. To jest znacznie, dużo droższe niż prawdziwe zapytanie najbliższego sąsiedztwa, które może wybrać najlepsze wyniki bezpośrednio z indeksu, nawet nie patrząc na resztę.

row_number() z pustą definicją okna odzwierciedla tylko kolejność utworzoną przez ORDER BY tego samego SELECT .

Powiązane odpowiedzi:

Jeśli chodzi o Twój przedmiot 3. , dodałem odpowiedź na zadane pytanie, która powinna to wyjaśnić:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres FOR LOOP

  2. Jak przechowywać plik pdf w bazie postgresql za pomocą serwletów?

  3. Pobieranie NoSuchMethodError:javax.persistence.Table.indexes() podczas wykonywania zapytania JPA

  4. Problem podczas pobierania rekordów z pustą tablicą

  5. Błąd ActiveRecord::StatementInvalid, PG::UndefinedTable, ale wygenerowany SQL działa