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

Menemukan string serupa dengan PostgreSQL dengan cepat

Cara Anda memilikinya, kesamaan antara setiap elemen dan setiap elemen lain dari tabel harus dihitung (hampir gabungan silang). Jika tabel Anda memiliki 1000 baris, itu sudah 1.000.000 (!) perhitungan kesamaan, sebelum mereka dapat diperiksa terhadap kondisi dan diurutkan. Berskala sangat.

Gunakan SET pg_trgm.similarity_threshold dan % operator sebagai gantinya. Keduanya disediakan oleh pg_trgm modul. Dengan cara ini, indeks trigram GiST dapat digunakan dengan efek yang luar biasa.

Parameter konfigurasi pg_trgm.similarity_threshold menggantikan fungsi set_limit() dan show_limit() di Postgres 9.6. Fungsi yang tidak digunakan lagi masih berfungsi (pada Postgres 13). Selain itu, kinerja indeks GIN dan GiST meningkat dalam banyak hal sejak Postgres 9.1.

Coba saja:

SET pg_trgm.similarity_threshold = 0.8;  -- Postgres 9.6 or later
  
SELECT similarity(n1.name, n2.name) AS sim, n1.name, n2.name
FROM   names n1
JOIN   names n2 ON n1.name <> n2.name
               AND n1.name % n2.name
ORDER  BY sim DESC;

Lebih cepat dengan urutan besarnya, tapi masih lambat.

pg_trgm.similarity_threshold adalah opsi "disesuaikan", yang dapat ditangani seperti opsi lainnya. Lihat:

  • Meminta parameter (pengaturan postgresql.conf) seperti "max_connections"

Anda mungkin ingin membatasi jumlah kemungkinan pasangan dengan menambahkan prasyarat (seperti mencocokkan huruf pertama) sebelum penggabungan silang (dan dukung itu dengan indeks fungsional yang cocok). Performa gabungan silang memburuk dengan O(N²) .

Ini tidak berfungsi karena Anda tidak dapat merujuk ke kolom keluaran di WHERE atau HAVING klausa:

WHERE ... sim > 0.8

Itu menurut standar SQL (yang ditangani agak longgar oleh RDBMS tertentu lainnya). Sebaliknya:

ORDER BY sim DESC

Karya karena kolom keluaran bisa digunakan dalam GROUP BY dan ORDER BY . Lihat:

  • Penggunaan kembali hasil komputasi PostgreSQL dalam kueri pemilihan

Kasus uji

Saya menjalankan pengujian cepat di server pengujian lama untuk memverifikasi klaim saya.
PostgreSQL 9.1.4. Waktu yang diambil dengan EXPLAIN ANALYZE (terbaik dari 5).

CREATE TEMP table t AS 
SELECT some_col AS name FROM some_table LIMIT 1000;  -- real life test strings

Tes putaran pertama dengan indeks GIN:

CREATE INDEX t_gin ON t USING gin(name gin_trgm_ops);  -- round1: with GIN index

Putaran kedua tes dengan indeks GIST:

DROP INDEX t_gin;
CREATE INDEX t_gist ON t USING gist(name gist_trgm_ops);

Kueri baru:

SELECT set_limit(0.8);

SELECT similarity(n1.name, n2.name) AS sim, n1.name, n2.name
FROM   t n1
JOIN   t n2 ON n1.name <> n2.name
           AND n1.name % n2.name
ORDER  BY sim DESC;

Indeks GIN digunakan, 64 klik:total waktu proses:484.022 md
indeks GIST digunakan, 64 klik:total waktu proses:248.772 md

Permintaan lama:

SELECT (similarity(n1.name, n2.name)) as sim, n1.name, n2.name
FROM   t n1, t n2
WHERE  n1.name != n2.name
AND    similarity(n1.name, n2.name) > 0.8
ORDER  BY sim DESC;

Indeks GIN tidak digunakan, 64 klik:total waktu proses:6345.833 md
indeks GIST tidak digunakan, 64 klik:total waktu proses:6335.975 md

Jika tidak, hasil yang identik. Sarannya bagus. Dan ini untuk hanya 1000 baris !

GIN atau GiST?

GIN sering memberikan kinerja membaca yang superior:

  • Perbedaan antara indeks GiST dan GIN

Tapi tidak dalam kasus khusus ini!

Ini dapat diimplementasikan dengan cukup efisien oleh indeks GiST, tetapi tidak oleh indeks GIN.

  • Indeks multikolom pada 3 bidang dengan tipe data yang heterogen



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menghubungkan Postgres ke server localhost menggunakan pgAdmin di Ubuntu?

  2. Mengintegrasikan PostgreSQL Dengan Sistem Otentikasi

  3. Bagaimana Tan() Bekerja di PostgreSQL

  4. Melarikan diri dari nama kolom seperti kata kunci di Postgres

  5. Kembalikan daftar yang dikelompokkan dengan kemunculan menggunakan Rails dan PostgreSQL