All Products
Search
Document Center

PolarDB:rum (akselerasi pencarian teks penuh)

Last Updated:Jan 06, 2026

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)

    Catatan

    Anda 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 ekstensi smlar. Karena konflik ini, Anda tidak dapat membuat dan menggunakan kedua ekstensi tersebut dalam skema database yang sama. Sebelum menginstal ekstensi RUM, pastikan ekstensi smlar tidak 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 INSERT atau UPDATE yang sering, evaluasi secara hati-hati overhead write yang diperkenalkan oleh ekstensi RUM.

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 hash atau tetap menggunakan indeks GIN.

Pencarian Awalan

Didukung.

Didukung oleh rum_tsvector_ops. Tidak didukung oleh seri hash.

Jika pencarian awalan merupakan kebutuhan inti, hindari penggunaan indeks RUM hash.

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_ops atau rum_tsvector_hash_addon_ops tidak 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.

Catatan

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 @@ B

Kiri: tsvector, Kanan: tsquery

bool

Mengembalikan apakah vektor teks penuh cocok dengan kondisi kueri. Melakukan perhitungan jarak.

A <=> B

Kiri: tsvector, Kanan: tsquery

float4

Mengembalikan nilai jarak antara vektor teks penuh dan kondisi kueri. Nilai yang lebih kecil menunjukkan relevansi yang lebih tinggi.

timestamp, timestamptz, int2, int4, int8, float4, float8, money, oid

float8

Mengembalikan selisih absolut antara dua nilai.

  • Selisih waktu dalam detik, akurat hingga enam tempat desimal (mikrodetik).

  • Selisih uang dalam sen, akurat hingga sen.

A <=| B

timestamp, timestamptz, int2, int4, int8, float4, float8, money, oid

float8

Mengembalikan B - A hanya jika A ≤ B. Jika tidak, mengembalikan tak hingga.

A |=> B

timestamp, timestamptz, int2, int4, int8, float4, float8, money, oid

float8

Mengembalikan A - B hanya jika A > B. Jika tidak, mengembalikan tak hingga.

Kelas Operator

Kelas Operator

Tipe Data yang Berlaku

Operator Utama yang Didukung

Fungsi Inti dan Deskripsi

rum_tsvector_ops

tsvector

  • WHERE: A @@ B

  • ORDER BY: A <=> B

Menyimpan lexeme dan informasi posisinya dari tsvector. Mendukung pencarian teks penuh, pencarian awalan, dan pengurutan berdasarkan relevansi. Ini adalah kelas operator yang paling umum digunakan untuk pencarian teks penuh.

rum_tsvector_hash_ops

tsvector

  • WHERE: A @@ B

  • ORDER BY: A <=> B

Menyimpan nilai hash dan informasi posisi dari lexeme tsvector.

  • Mendukung pencarian teks penuh dan pengurutan berdasarkan relevansi, tetapi tidak mendukung pencarian awalan.

  • Ukuran indeks mungkin lebih kecil dibandingkan dengan rum_tsvector_ops.

  • Tabrakan hash dapat terjadi selama pencarian, yang memerlukan pemeriksaan ulang.

rum_<TYPE>_ops

int2, int4, int8, float4, float8, money, oid, time, timetz, date, interval, macaddr, inet, cidr, text, varchar, char, bytea, bit, varbit, numeric, timestamp, timestamptz

  • WHERE: Untuk tipe data yang berlaku, mendukung <, <=, =, >=, dan > antara nilai-nilai dengan tipe yang sama.

  • ORDER BY: Untuk int2, int4, int8, float4, float8, money, oid, timestamp, dan timestamptz, mendukung operasi <=>, <=|, dan |=> antara nilai-nilai dengan tipe yang sama.

Menjalankan kueri rentang dan pengurutan jarak pada tipe data non-teks dan non-array.

rum_tsvector_addon_ops

tsvector

WHERE: A @@ B

Menambahkan data dari kolom tambahan (seperti timestamp) ke indeks tsvector. Hal ini mendukung pencarian teks penuh pada kolom utama sekaligus memungkinkan pengurutan efisien pada kolom tambahan.

Catatan

Tipe data kolom tambahan harus didukung oleh kelas operator rum_<TYPE>_ops yang sesuai. Untuk menggunakan indeks sebagai akselerator, pengurutan harus menggunakan operator <=>, <=|, atau |=>.

rum_tsvector_hash_addon_ops

tsvector

WHERE: A @@ B

Fungsi yang sama dengan rum_tsvector_addon_ops.

  • Karena menyimpan nilai hash dari lexeme, tidak mendukung pencarian awalan.

  • Ukuran indeks mungkin lebih kecil dibandingkan dengan rum_tsvector_addon_ops.

  • Tabrakan hash dapat terjadi, sehingga memerlukan pemeriksaan ulang.

  • Pencarian mungkin lebih lambat dibandingkan dengan rum_tsvector_addon_ops.

rum_tsquery_ops

tsquery

WHERE: A @@ B

Digunakan untuk mengindeks kolom tsquery. Dapat mempercepat kueri secara terbalik, dengan cepat menemukan kondisi kueri yang tersimpan (tsquery) yang cocok dengan dokumen tertentu (tsvector).

rum_anyarray_ops

anyarray, misalnya, int[], text[], varchar[]

  • WHERE:

    • &&: Apakah array tumpang tindih (memiliki elemen yang sama)?

    • @>: Apakah array kiri berisi semua elemen array kanan?

    • <@: Terdapat di dalam.

    • =: Apakah array sama?

    • : Apakah array mirip? (Kemiripan dihitung. Jika melebihi ambang batas, array dianggap mirip.)

  • ORDER BY

    • <=>: Jarak antara dua array.

Mengindeks tipe array. Mendukung operasi array seperti contains dan overlap, serta mendukung pengurutan berdasarkan jarak antar array.

rum_anyarray_addon_ops

anyarray, misalnya, int[], text[], varchar[]

  • WHERE:

    • &&: Apakah array tumpang tindih (memiliki elemen yang sama)?

    • @>: Apakah array kiri berisi semua elemen array kanan?

    • <@: Terdapat di dalam.

    • =: Apakah array sama?

    • : Apakah array mirip? (Kemiripan dihitung. Jika melebihi ambang batas, array dianggap mirip.)

  • ORDER BY

    • <=>: Jarak antara dua 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 rum_<TYPE>_ops yang sesuai. Untuk menggunakan indeks sebagai akselerator, pengurutan harus menggunakan operator <=>, <=|, atau |=>.

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.

  1. 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');
  2. Buat indeks RUM: Gunakan kelas operator rum_tsvector_ops untuk membuat indeks RUM pada kolom tsvector.

    CREATE INDEX t1_t_vec_idx ON t1 USING rum (t_vec rum_tsvector_ops);
  3. 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, penggunaan ORDER BY mengurutkan 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.

  1. Persiapkan data: Buat tabel yang berisi kolom tsvector dan 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');
  2. Buat indeks RUM dengan kolom tambahan: Gunakan kelas operator rum_tsvector_addon_ops dan tentukan kolom tambahan serta kolom indeks utama dalam klausa WITH.

    CREATE INDEX tsts_idx ON tsts USING rum (t rum_tsvector_addon_ops, d) WITH (attach = 'd', to = 't');
    Catatan

    Sintaks kunci WITH (attach = 'd', to = 't') melampirkan nilai kolom d (kolom tambahan, yaitu timestamp) ke entri indeks kolom t (kolom indeks utama bertipe tsvector). Hal ini memungkinkan database menggunakan indeks pada kolom t untuk pencarian teks penuh dan informasi kolom tambahan d untuk pengurutan efisien dalam satu pemindaian indeks. Proses ini menghindari lookup ke tabel dan secara signifikan meningkatkan performa.

  3. 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.

  1. 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}');
  2. Buat indeks RUM untuk array: Gunakan kelas operator rum_anyarray_ops untuk membuat indeks pada kolom array.

    CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops);
  3. Jalankan kueri array dan pengurutan: Lakukan kueri untuk catatan yang berisi elemen 1 dan 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.

  1. 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');
  2. Buat indeks RUM untuk tsquery:

    CREATE INDEX query_idx ON query USING rum(q rum_tsquery_ops);
  3. Jalankan kueri pencocokan terbalik: Gunakan tsvector dari artikel baru untuk mencocokkan semua aturan tsquery yang 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