Ekstensi RUM menyediakan alternatif terhadap Generalized Inverted Index (GIN) bawaan PostgreSQL untuk pencarian teks penuh pada volume teks yang besar. Ekstensi ini memungkinkan pengurutan hasil pencarian berdasarkan relevansi, timestamp, atau bidang lainnya. Indeks GIN tradisional memerlukan lookup ke tabel untuk mengurutkan hasil, yang dapat menyebabkan bottleneck performa. Sebaliknya, ekstensi RUM menyimpan informasi posisi dan data tambahan yang diperlukan langsung di dalam indeks, sehingga menghindari lookup tersebut dan meningkatkan performa kueri hingga beberapa kali lipat dalam skenario tertentu.
Kesesuaian
PolarDB for PostgreSQL mendukung versi berikut:
PostgreSQL 18 (versi mesin minor 2.0.18.1.2.0 dan yang lebih baru)
PostgreSQL 17 (versi mesin minor 2.0.17.6.4.0 dan yang lebih baru)
PostgreSQL 16 (versi mesin minor 2.0.16.8.3.0 dan yang lebih baru)
PostgreSQL 15 (versi mesin minor 2.0.15.7.1.1 dan yang lebih baru)
PostgreSQL 14 (versi mesin minor 2.0.14.5.3.0 dan yang lebih baru)
CatatanAnda dapat melihat versi mesin minor di Konsol atau dengan menjalankan pernyataan
SHOW polardb_version;. Jika versi Anda tidak memenuhi persyaratan, upgrade versi mesin minor. Untuk informasi selengkapnya, lihat Lihat versi mesin minor.Kompatibilitas ekstensi: Operator
%dari ekstensi RUM bentrok dengan operator%dari ekstensismlar. Karena konflik ini, Anda tidak dapat membuat dan menggunakan kedua ekstensi tersebut dalam skema database yang sama. Sebelum menginstal ekstensi RUM, pastikan ekstensismlartidak digunakan di lingkungan Anda, atau instal kedua ekstensi tersebut di skema yang berbeda.
Skenario
Tinjau tabel berikut untuk memahami perbedaan utama antara ekstensi RUM dan indeks GIN native. Informasi ini dapat membantu Anda memilih opsi terbaik untuk skenario bisnis Anda.
Dimensi Perbandingan | Indeks GIN (Bawaan) | Indeks RUM | Rekomendasi |
Keunggulan Utama | Performa write yang baik. Ukuran indeks relatif kecil. | Performa pengurutan tinggi. Mendukung pencarian frasa dan pengurutan berdasarkan kolom tambahan. | Untuk skenario yang memerlukan pengurutan hasil pencarian, ekstensi RUM adalah pilihan utama. |
Performa Pengurutan | Lambat. Memerlukan lookup ke tabel untuk memperoleh data pengurutan. Performa menurun tajam seiring peningkatan volume data. | Cepat. Melakukan pengurutan langsung di dalam indeks. Tidak memerlukan lookup ke tabel. | Gunakan ekstensi RUM jika Anda sering mengurutkan hasil pencarian teks penuh, misalnya berdasarkan relevansi, waktu, atau harga. |
Pencarian Frasa | Lambat. Memerlukan lookup ke tabel untuk memperoleh informasi posisi kata guna memverifikasi frasa. | Cepat. Informasi posisi kata sudah disimpan di dalam indeks. Tidak memerlukan lookup ke tabel. | Gunakan ekstensi RUM untuk skenario yang memerlukan pencarian frasa berkinerja tinggi. |
Pengurutan Berdasarkan Kolom Tambahan | Tidak didukung. Tidak dapat menyimpan informasi dari kolom tambahan, seperti timestamp, di dalam indeks. | Didukung. Anda dapat melampirkan kolom lain ke indeks untuk pengurutan kustom berkinerja tinggi. | Ekstensi RUM memiliki keunggulan signifikan dalam skenario yang memerlukan pengurutan berdasarkan bidang seperti waktu publikasi artikel atau waktu pembaruan. |
Performa Write | Relatif cepat. | Relatif lambat karena harus memelihara skema indeks yang lebih kompleks. | Untuk tabel yang intensif write dengan operasi |
Ukuran Indeks | Relatif kecil. | Relatif besar karena memerlukan ruang tambahan untuk menyimpan informasi posisi dan informasi tambahan. | Evaluasi biaya penyimpanan Anda. Jika ukuran indeks menjadi bottleneck utama, pertimbangkan untuk menggunakan indeks RUM |
Pencarian Awalan | Didukung. | Didukung oleh | Jika pencarian awalan merupakan kebutuhan inti, hindari penggunaan indeks RUM |
Ekstensi RUM menukar ruang dengan waktu. Ekstensi ini meningkatkan ukuran indeks dan overhead write untuk secara signifikan meningkatkan performa dalam skenario kueri tertentu, terutama pengurutan. Jika bisnis inti Anda melibatkan pencarian teks penuh dengan pengurutan kompleks, ekstensi RUM adalah pilihan ideal. Namun, jika bisnis Anda terutama bersifat write-intensive atau hanya memerlukan pencocokan teks sederhana, indeks GIN lebih hemat biaya.
Perhatian
Performa write dan ukuran indeks: Untuk mempercepat kueri, indeks RUM menyimpan informasi tambahan, seperti posisi kata. Hal ini membuat ukuran indeks lebih besar dibandingkan indeks GIN dan meningkatkan overhead pembuatan indeks selama operasi write dan update data. Oleh karena itu, Anda harus mengevaluasi secara hati-hati biaya ekstensi RUM dalam skenario yang intensif write dan ketika storage space menjadi pertimbangan.
Skema yang tidak mendukung pencarian awalan: Indeks yang dibuat dengan kelas operator
rum_tsvector_hash_opsataurum_tsvector_hash_addon_opstidak mendukung pencarian awalan. Hal ini karena mereka menyimpan nilai hash dari lexeme, bukan teks aslinya.
Instalasi dan uninstall ekstensi
Instal ekstensi
Jalankan perintah berikut di database Anda untuk membuat ekstensi RUM.
CREATE EXTENSION rum;Copot pemasangan ekstensi
Jika Anda tidak lagi memerlukan ekstensi RUM, jalankan perintah berikut untuk meng-uninstall-nya.
DROP EXTENSION rum;Penggunaan
Ekstensi RUM menyediakan beberapa kelas operator untuk mendukung berbagai tipe data dan skenario kueri. Anda dapat memilih kelas operator yang sesuai untuk membuat indeks berdasarkan kebutuhan spesifik Anda.
Kelas operator mendefinisikan sekumpulan operasi yang digunakan oleh indeks RUM untuk memproses tipe data tertentu. Hal ini memungkinkan indeks untuk menyimpan dan mengambil data tipe tersebut dengan benar. Setiap kelas operator mencakup sekumpulan operator tertentu. Saat Anda menggunakan operator yang didukung ini dalam klausa WHERE atau ORDER BY, PostgreSQL dapat menggunakan indeks RUM untuk mempercepat kueri.
Oleh karena itu, pemilihan kelas operator yang tepat sangat penting untuk memastikan efektivitas indeks RUM. Untuk informasi selengkapnya, lihat Operator Classes and Operator Families.
Operator
Operator | Tipe yang Didukung | Tipe Nilai Kembalian | Deskripsi |
A | Kiri: |
| Mengembalikan apakah vektor teks penuh cocok dengan kondisi kueri. Melakukan perhitungan jarak. |
A | Kiri: |
| Mengembalikan nilai jarak antara vektor teks penuh dan kondisi kueri. Nilai yang lebih kecil menunjukkan relevansi yang lebih tinggi. |
|
| Mengembalikan selisih absolut antara dua nilai.
| |
A |
|
| Mengembalikan |
A |
|
| Mengembalikan |
Kelas Operator
Kelas Operator | Tipe Data yang Berlaku | Operator Utama yang Didukung | Fungsi Inti dan Deskripsi |
|
|
| Menyimpan lexeme dan informasi posisinya dari |
|
|
| Menyimpan nilai hash dan informasi posisi dari lexeme
|
|
|
| Menjalankan kueri rentang dan pengurutan jarak pada tipe data non-teks dan non-array. |
|
|
| Menambahkan data dari kolom tambahan (seperti Catatan Tipe data kolom tambahan harus didukung oleh kelas operator |
|
|
| Fungsi yang sama dengan
|
|
|
| Digunakan untuk mengindeks kolom |
|
|
| Mengindeks tipe array. Mendukung operasi array seperti contains dan overlap, serta mendukung pengurutan berdasarkan jarak antar array. |
|
|
| Menambahkan data dari kolom tambahan ke indeks array untuk mendukung skenario kueri yang lebih kompleks. Catatan Tipe data kolom tambahan harus didukung oleh kelas operator |
Skenario 1: Mempercepat pengurutan berdasarkan relevansi untuk hasil pencarian teks penuh
Saat Anda perlu mengurutkan hasil pencarian teks penuh berdasarkan relevansi, Anda dapat menggunakan indeks RUM untuk menghindari overhead pengurutan tambahan yang diperlukan oleh indeks GIN dan mencapai pengurutan berkinerja tinggi.
Persiapkan data: Pertama, buat tabel uji.
CREATE TABLE t1( t text, t_vec tsvector GENERATED ALWAYS AS (to_tsvector('pg_catalog.english', t)) STORED ); -- Masukkan data uji INSERT INTO t1(t) VALUES ('The situation is most beautiful'); INSERT INTO t1(t) VALUES ('It is a beautiful'); INSERT INTO t1(t) VALUES ('It looks like a beautiful place');Buat indeks RUM: Gunakan kelas operator
rum_tsvector_opsuntuk membuat indeks RUM pada kolomtsvector.CREATE INDEX t1_t_vec_idx ON t1 USING rum (t_vec rum_tsvector_ops);Jalankan kueri pengurutan berdasarkan relevansi: Gunakan operator
<=>untuk melakukan kueri dan pengurutan. Operator ini menghitung jarak antara kueri dan teks. Jarak yang lebih kecil menunjukkan relevansi yang lebih tinggi. Oleh karena itu, penggunaanORDER BYmengurutkan hasil berdasarkan relevansi.SET enable_seqscan TO off; SELECT t, t_vec <=> to_tsquery('english', 'beautiful | place') AS rank FROM t1 WHERE t_vec @@ to_tsquery('english', 'beautiful | place') ORDER BY t_vec <=> to_tsquery('english', 'beautiful | place');Hasil berikut dikembalikan:
t | rank ---------------------------------+--------- It looks like a beautiful place | 8.22467 The situation is most beautiful | 16.4493 It is a beautiful | 16.4493
Skenario 2: Mempercepat pengurutan gabungan pencarian teks penuh dan kolom tambahan
Dalam skenario seperti analisis log atau pencarian E-dagang, Anda sering perlu melakukan pencarian teks penuh dan mengurutkan hasil berdasarkan bidang tambahan, seperti timestamp atau harga. Fitur RUM add-on memungkinkan Anda menyimpan informasi dari kolom tambahan di dalam indeks. Hal ini memungkinkan kueri dan pengurutan gabungan yang efisien.
Persiapkan data: Buat tabel yang berisi kolom
tsvectordan kolom timestamp, lalu masukkan data sampel.CREATE TABLE tsts (id int, t tsvector, d timestamp); INSERT INTO tsts VALUES (354, to_tsvector('wr qh'), '2016-05-16 14:21:22.326724'), (355, to_tsvector('wr qh'), '2016-05-16 13:21:22.326724'), (356, to_tsvector('ts op'), '2016-05-16 18:21:22.326724'), (358, to_tsvector('ts op'), '2016-05-16 23:21:22.326724'), (371, to_tsvector('wr qh'), '2016-05-17 06:21:22.326724'), (406, to_tsvector('wr qh'), '2016-05-18 17:21:22.326724'), (415, to_tsvector('wr qh'), '2016-05-19 02:21:22.326724');Buat indeks RUM dengan kolom tambahan: Gunakan kelas operator
rum_tsvector_addon_opsdan tentukan kolom tambahan serta kolom indeks utama dalam klausaWITH.CREATE INDEX tsts_idx ON tsts USING rum (t rum_tsvector_addon_ops, d) WITH (attach = 'd', to = 't');CatatanSintaks kunci
WITH (attach = 'd', to = 't')melampirkan nilai kolomd(kolom tambahan, yaitu timestamp) ke entri indeks kolomt(kolom indeks utama bertipetsvector). Hal ini memungkinkan database menggunakan indeks pada kolomtuntuk pencarian teks penuh dan informasi kolom tambahanduntuk pengurutan efisien dalam satu pemindaian indeks. Proses ini menghindari lookup ke tabel dan secara signifikan meningkatkan performa.Jalankan kueri pengurutan gabungan: Lakukan kueri untuk catatan yang berisi kata tertentu dan urutkan berdasarkan kedekatan timestamp-nya terhadap waktu target.
SET enable_seqscan TO off; EXPLAIN (costs off) SELECT id, d, d <=> '2016-05-16 14:21:25' AS distance FROM tsts WHERE t @@ 'wr&qh' ORDER BY d <=> '2016-05-16 14:21:25' LIMIT 5;Rencana eksekusi berikut menunjukkan bahwa pengurutan dan penyaringan keduanya diselesaikan dalam satu pemindaian indeks.
QUERY PLAN ------------------------------------------------------------------------------ Limit -> Index Scan using tsts_idx on tsts Index Cond: (t @@ '''wr'' & ''qh'''::tsquery) Order By: (d <=> '2016-05-16 14:21:25'::timestamp without time zone)Hasil berikut dikembalikan:
id | d | distance -----+----------------------------+--------------- 354 | 2016-05-16 14:21:22.326724 | 2.673276 355 | 2016-05-16 13:21:22.326724 | 3602.673276 371 | 2016-05-17 06:21:22.326724 | 57597.326724 406 | 2016-05-18 17:21:22.326724 | 183597.326724 415 | 2016-05-19 02:21:22.326724 | 215997.326724
Skenario 3: Mempercepat kueri array dan pengurutan berdasarkan kemiripan
Untuk skenario seperti sistem tagging atau persona pengguna, Anda perlu melakukan kueri array yang berisi elemen tertentu secara efisien dan mengurutkannya berdasarkan tingkat tumpang tindih atau kemiripan.
Persiapkan data:
CREATE TABLE test_array (id serial, i int2[]); INSERT INTO test_array(i) VALUES ('{}'), ('{0}'), ('{1,2,3,4}'), ('{1,2,3}'), ('{1,2}'), ('{1}');Buat indeks RUM untuk array: Gunakan kelas operator
rum_anyarray_opsuntuk membuat indeks pada kolom array.CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops);Jalankan kueri array dan pengurutan: Lakukan kueri untuk catatan yang berisi elemen
1dan urutkan berdasarkan kemiripan dengan{1}.SELECT * FROM test_array WHERE i && '{1}' -- Operator '&&' menunjukkan tumpang tindih array. ORDER BY i <=> '{1}' ASC; -- Operator '<=>' menghitung jarak antar array. Nilai yang lebih kecil menunjukkan kemiripan yang lebih besar.Hasil berikut dikembalikan:
i ----------- {1} {1,2} {1,2,3} {1,2,3,4}
Skenario 4: Indeks terbalik untuk mencocokkan aturan kueri dengan cepat
Saat membangun sistem untuk langganan pengguna atau pencocokan aturan notifikasi, Anda perlu mencocokkan data baru, seperti artikel, dengan banyak aturan kueri yang ada, seperti kata kunci langganan pengguna. Ekstensi RUM mendukung pembuatan indeks pada tipe tsquery untuk melakukan pencocokan terbalik yang efisien.
Persiapkan data aturan kueri:
CREATE TABLE query (id serial, q tsquery, tag text); INSERT INTO query (q, tag) VALUES ('supernova & star', 'sn'), ('black', 'color'), ('big & bang & black & hole', 'bang'), ('spiral & galaxy', 'shape'), ('black & hole', 'color');Buat indeks RUM untuk
tsquery:CREATE INDEX query_idx ON query USING rum(q rum_tsquery_ops);Jalankan kueri pencocokan terbalik: Gunakan
tsvectordari artikel baru untuk mencocokkan semua aturantsqueryyang memenuhi syarat.SELECT * FROM query WHERE to_tsvector('black holes never exists before we think about them') @@ q;Hasil berikut dikembalikan:
id | q | tag -----+----------+------- 2 | 'black' | color