PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Mengoptimalkan kueri kesamaan postgres (pg_trgm + indeks gin)

Saya berharap banyak hasil yang lebih cepat dengan pendekatan ini:

1.

Buat indeks GiST dengan 1 kolom yang berisi nilai gabungan:

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

Ini mengasumsikan semua 3 kolom didefinisikan NOT NULL (Anda tidak menentukan). Jika tidak, Anda perlu melakukan lebih banyak.
Mengapa tidak menyederhanakan dengan concat_ws() ?

2.

Gunakan yang tepat kueri, cocok dengan indeks di atas:

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;

Ekspresi dalam WHERE dan ORDER BY harus cocok dengan ekspresi indeks!

Khususnya ORDER BY rank (seperti yang Anda miliki) akan selalu berkinerja buruk untuk LIMIT kecil memilih dari kumpulan baris kualifikasi yang jauh lebih besar, karena tidak dapat menggunakan indeks secara langsung:Ekspresi canggih di balik rank harus dihitung untuk setiap baris kualifikasi, maka semua harus diurutkan sebelum pilihan kecil pertandingan terbaik dapat dikembalikan. Ini jauh, jauh lebih mahal daripada kueri tetangga terdekat yang sebenarnya yang dapat memilih hasil terbaik dari indeks secara langsung bahkan tanpa melihat sisanya.

row_number() dengan definisi jendela kosong hanya mencerminkan pemesanan yang dihasilkan oleh ORDER BY dari SELECT . yang sama .

Jawaban terkait:

Adapun item Anda 3. , saya menambahkan jawaban untuk pertanyaan yang Anda rujuk, yang seharusnya menjelaskannya:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. LIMIT yang dikelompokkan di PostgreSQL:tampilkan N baris pertama untuk setiap grup?

  2. PostgreSQL:Kueri tidak memiliki tujuan untuk data hasil

  3. Di Redshift/Postgres, bagaimana cara menghitung baris yang memenuhi suatu kondisi?

  4. Bagaimana cara mengubah array json menjadi array int postgres di postgres 9.3

  5. RedShift - Beban CSV dengan Line Break