Full-text search di PostgreSQL selama ini punya dua jalan yang sama-sama tidak nyaman. Jalan pertama: pakai tsvector dan GIN bawaan Postgres, gratis dan sudah terintegrasi, tapi query bahasa alaminya kaku, ranking-nya seadanya, dan beban indexing bisa bikin write lambat. Jalan kedua: bawa Elasticsearch atau OpenSearch, dapat BM25 dan analisis teks yang serius, tapi bayar dengan dua sistem sumber kebenaran, pipeline sinkronisasi, dan ops yang berlipat. PlanetScale masuk ke celah itu pada 16 September 2026 dengan merilis TIN, ekstensi full-text search yang mereka klaim sebagai teks lengkap yang cepat dan andal untuk Postgres.
Nama TIN adalah singkatan harfiah: Text INdex. Yang membuatnya menarik bukan namanya, tapi daftar kemampuan yang mereka targetkan dan keputusan-keputusan implementasi di baliknya. Artikel ini bedah apa yang diumumkan, dari announcement resminya di blog PlanetScale.
Apa yang TIN Bawa ke Meja
Pemasangannya lewat CREATE INDEX biasa dengan access method sendiri:
CREATE INDEX an_index_name ON table_name USING tin(text_column_name);
SELECT * FROM table_name
WHERE text_column_name ==> 'some words';
Operator pencarian kata per kata itu, dua tanda sama dengan dan satu tanda besar, adalah surface query utamanya. Di balik surface itu, PlanetScale menyebut standar yang mereka pasang untuk teks index yang bagus harus mendukung:
- Ekspresi boolean, phrase query, dan span query
- Pencocokan term dengan fuzzy, wildcard, dan regular expression
- Case dan accent folding
- Query COUNT(*) yang benar, plus top-k dengan skor BM25
Dan yang paling penting di Postgres: semua itu harus tetap jalan berdampingan dengan join, klausa WHERE rumit yang menggabungkan kolom teks dengan kolom lain, update terus-menerus, replikasi, dan backup. Ini yang membedakan indeks di dalam database relasional dari search engine eksternal: TIN tunduk pada MVCC, visibilitas baris per transaksi, sesuatu yang secara desain bermusuhan dengan indeks inversi klasik.
TIN dirilis langsung sebagai GA, tidak ada fase beta panjang, tersedia untuk database Postgres di platform mereka dan juga Neki, produk sharded Postgres mereka. Untuk pengguna Postgres umum, ini ekstensi open yang bisa dibandingkan dengan opsi seperti ParadeDB atau pg_search, dengan satu perbedaan klaim yang bikin mereka percaya diri: benchmark.
Angka Benchmark yang Mereka Luncurkan
Posting PlanetScale menyusun benchmark-nya jujur dengan struktur beban kerja, bukan satu angka ajaib. Beberapa dimensi yang diuji: waktu dan ukuran build indeks, mixed query dengan hasil top-10 berperingkat BM25, conjunction dan phrase query, disjunction yang dijalankan bersamaan dengan write, serta kasus ketika indeks cukup muat di memori. Detail angkanya ada di posting resmi mereka dan berubah mengikuti versi, jadi angka yang harus dipercaya adalah hasil rerun di dataset lo sendiri.
Tapi bagian yang paling menarik untuk developer level arsitektur justru penjelasan "Why TIN is fast", karena di sana ada tiga keputusan desain yang layak dipinjam pemikirannya bahkan tanpa menginstal ekstensinya.
Keputusan Desain 1: ID Dokumen 48-bit
Indeks inversi secara tradisional memetakan term ke daftar dokumen, dan daftar itu berisi ID dokumen yang di-compress dengan teknik seperti FOR (frame of reference). Postgres sudah punya identitas baris bernama ctid, tapi ctid berubah saat UPDATE dan VACUUM, sedangkan indeks teks tidak boleh ikut hancur setiap kali baris berpindah. TIN memperkenalkan identifier 48-bit per baris yang stabil, dengan judul seksi di blog mereka yang menggemaskan: "48-bit identifiers are crazy".
Ruang 48 bit itu 281 triliun lebih ID per tabel. Poinnya bukan pamer angka, tapi konsekuensi desain: dengan ID yang kecil dan monotonik, posting list bisa di-compress jauh lebih rapat, dan scan bisa jalan dengan aritmetika SIMD di atas blok integers, bukan pointer chasing yang membunuh cache.
Keputusan Desain 2: Work Elision dan Vektorisasi
Query teks sering melewati term yang sudah pasti tidak relevan, istilah stopword-like, atau hasil folding yang tabrakan. "Work elision" adalah keluarga teknik untuk memotong pekerjaan itu sebelum dieksekusi: struktur bloom-style di level posting list dan blok membuat evaluator bisa menyimpulkan "tidak ada satupun baris di blok ini yang mungkin cocok" dalam satu operasi vektor, lalu melompati seluruh blok. Ini pola yang sama yang membuat index scan modern di database kolom terasa ajaib, dibawa ke dunia indeks teks.
Keputusan Desain 3: Menjinakkan MVCC dengan Segmen
Bagian tersulit full-text search di dalam Postgres adalah kenyataan bahwa data berubah terus. Tin memilih pendekatan indeks bergaya LSM: dokumen baru masuk ke segmen, segmen-segmen kecil di-merge berkala menjadi segmen besar, dan visibilitas MVCC ditangani dengan kombinasi bitmap dan filter saat query berjalan, bukan dengan mengedit posting list setiap ada UPDATE. Konsekuensinya klasik LSM: write murah, ada pekerjaan latar belakang (merge) yang harus dijadwalkan, dan ukuran indeks tumbuh sebelum dipangkas ulang.
Kapan Pakai TIN, Kapan tsvector Cukup, Kapan Cari yang Lain
Aturan praktis yang masuk akal dari kemampuan-nya yang diumumkan:
- tsvector GIN bawaan masih juara untuk kasus sederhana: pencarian kata di kolom yang jarang berubah, tanpa kebutuhan ranking BM25 atau fuzzy, dan lo tidak ingin menambah ekstensi apa pun ke stack.
- TIN posisinya tepat ketika lo butuh BM25 top-k, phrase, wildcard, dan regex di dalam query yang juga melakukan join dan filter relasional, tanpa mau memelihara cluster search engine terpisah.
- Search engine eksternal tetap masuk akal ketika beban kerjanya bercampur analytics log, observability, atau skala korpus yang membuat merge biaya indeks di primary terlalu terasa.
Satu catatan penting untuk pembaca Indonesia: TIN diumumkan GA untuk Postgres di platform PlanetScale dan Neki. Untuk deployment Postgres self-managed, ketersediaan paket ekstensi mengikuti distribusi lo, jadi sebelum memplot arsitektur produksi, cek dulu daftar ekstensi yang tersedia di hosting database lo. Jangan mengarang asumsi.
Kenapa Ini Relevan Buat Developer Lokal
Kebanyakan aplikasi yang dibangun developer Indonesia butuh cari teks: katalog produk, tiket dukungan, dokumen internal, berita. Selama ini pilihan standarnya "pakai LIKE '%kata%' sambil nangis" atau "pasang Elasticsearch padahal yang dicari cuma 200 ribu baris". Lapisan opsi di tengah, indeks teks yang benar di dalam Postgres, sekarang makin ramai, dan itu baik. Kompetisi di sini menghasilkan hal yang paling langka di dunia database: ranking yang bisa diterima tanpa mengirim data keluar.
Buat yang mau langsung coba: baca posting pengumumannya lengkap dengan dataset dan setup benchmark-nya, lalu tiru di sampel data lo sendiri. Kesimpulan benchmark orang lain, sejujur apa pun, tetap opinion; angka di dataset lo yang jadi data.
BM25 itu Apa, dan Kenapa Semua Orang Sibuk Menyebutnya
Sebutan BM25 muncul terus di pengumuman TIN, jadi layak dijelaskan tanpa jargon. BM25 (Best Match 25, dari keluarga Okapi) adalah fungsi peringkat untuk information retrieval: memberi skor pada pasangan query-dokumen berdasarkan tiga hal yang intuitif. Kata query yang muncul lebih sering di dokumen menaikkan skor, tapi dengan saturasi, karena muncul 50 kali tidak membuat dokumen 50 kali lebih relevan. Kata yang langka di seluruh korpus menaikkan skor lebih tinggi daripada kata yang umum; ini logika inverse document frequency. Dokumen lebih panjang dihukum sedikit dibanding dokumen pendek dengan jumlah kemunculan kata yang sama, karena panjang menyediakan konteks yang membuat satu kemunculan kurang informatif.
Kenapa penting bahwa TIN menyebut BM25 top-k sebagai fitur kelas satu? Karena ranking yang baik adalah separuh dari pengalaman pencarian. tsvector punya sistem peringkat sendiri, ts_rank, yang secara fungsi lebih dekat ke "berapakah kepadatan kata ini" dan tidak mengenal statistik korpus sekental BM25. Dalam praktik, perbedaan ini terasa ketika query user longgar dan hasilnya banyak: ranking yang jelek membuat pencarian terasa rusak padahal datanya ada.
Yang Tidak Bisa Dilakukan TIN (Supaya Ekspektasi Masuk Akal)
Dari daftar fitur resminya, beberapa hal yang tidak muncul dan memang bukan tujuan TIN: pencarian semantik berbasis embedding, koreksi ejaan berbasis konteks kalimat, dan pemahaman query natural language. Fuzzy matching TIN bekerja di level term, cocokkan ejaan terdekat, bukan cari meaning. Kalau use case lo adalah "cari dokumen yang membahas topik gaji meskipun tidak ada kata gajinya", itu wilayah vector search, dan Postgres tetap bisa pakai pgvector berdampingan dengan indeks teks. Keduanya bukan pengganti, pelengkapnya.
Batasan lain yang jujur: TIN adalah ekstensi. Di Postgres self-managed, lo bertanggung jawab atas siklus upgrade-nya sendiri dan harus memastikan versi ekstensi seragam di semua node replika. Lo juga bertanggung jawab atas ritme maintenance merge di background kalau arsitekturnya LSM-like; jam merge yang jatuh di jam sibuk perlu dijadwalkan ulang, sesuatu yang jarang dipikirkan saat indeks masih kecil.
Protokol Evaluasi di Data Lo Sendiri
Sebelum menyimpulkan TIN cocok untuk aplikasi lo, jalankan ritual lima langkah ini di salinan dataset produksi:
- Siapkan staging dengan replika data terbesar lo, bukan tabel demo ratusan baris. Perbedaan indeks teks yang bagus dan biasa baru terlihat di skala.
- Ukur tiga hal terpisah: waktu build indeks awal, laju pertumbuhan ukuran indeks saat write terus jalan, dan latensi query pada campuran beban lo (top-k, COUNT, dan query gabungan dengan filter relasional).
- Rekam perilaku di bawah write bersamaan; benchmark read-only terlalu sering menipu karena tidak menyentuh jalur merge dan visibilitas MVCC.
- Bandingkan dengan baseline tsvector lo sekarang pada query yang sama, dengan koreksi hasil yang divalidasi manual, karena relevansi itu urusan data lo, bukan benchmark publik siapa pun.
- Baru putuskan. Kalau angka-angkanya menang dan ops-nya bisa lo tanggung, migrasi column per column, bukan seluruh database sekaligus.
PlanetScale sendiri mempublikasikan korpus dan setup environment benchmark mereka lengkap di posting announcement. Tiru metodenya, jangan telan hasilnya.
Sumber
- Blog PlanetScale: Introducing TIN: full-text search for Postgres, Eric Ridge dan Patrick Reynolds, 16 September 2026
- Dokumentasi akses method dan contoh sintaks sebagaimana dikutip dari posting tersebut
💬 Komentar (0)
Belum ada komentar. Jadilah yang pertama! 💬