Full-Text Index

Full-Text Index #

Dalam banyak sistem backend modern, pencarian teks adalah fitur yang tidak bisa dihindari: search artikel, search produk, search log, search knowledge base, dan sebagainya. Masalahnya, query pencarian teks yang salah bisa menjadi mimpi buruk bagi database.

Di sinilah Full-Text Index (FTI) hadir. Ia sering disebut sebagai solusi cepat untuk pencarian teks, tapi di saat yang sama juga sering disalahgunakan.

Artikel ini akan membahas:

  • Apa itu Full-Text Index
  • Bagaimana cara kerjanya
  • Kenapa ia bisa sangat mempengaruhi performa query database
  • Kesalahan umum penggunaan Full-Text Index
  • Best practice optimasi query Full-Text Index

Apa Itu Full-Text Index? #

Full-Text Index adalah jenis index khusus yang dirancang untuk melakukan pencarian teks berbasis kata (token), bukan pencocokan string mentah seperti LIKE '%keyword%'.

Berbeda dengan B-Tree index yang bekerja pada:

  • equality (=)
  • range (<, >, BETWEEN)

Full-Text Index bekerja pada:

  • kata
  • frasa
  • relevansi
  • ranking hasil

Contoh use case:

  • Search artikel berdasarkan isi konten
  • Search produk berdasarkan deskripsi
  • Search komentar atau review

Kenapa LIKE '%keyword%' Itu Buruk? #

Sebelum memahami Full-Text Index, kita perlu tahu kenapa solusi klasik ini bermasalah:

SELECT * FROM articles WHERE content LIKE '%database%';

Masalahnya:

  1. Tidak bisa memakai index B-Tree
  2. Database melakukan full table scan
  3. Kompleksitas O(n) terhadap jumlah row
  4. Semakin besar data → semakin lambat

Di tabel besar, query ini adalah performance killer.


Cara Kerja Full-Text Index (Secara Konseptual) #

Full-Text Index menggunakan konsep inverted index.

Alih-alih:

Row → Konten

Database menyimpan:

Kata → List Row ID

Contoh:

KataRow ID
database1, 3, 7
index2, 3
performance1, 7

Saat query:

MATCH(content) AGAINST('database index')

Database cukup:

  1. Cari kata database dan index
  2. Ambil intersection row ID
  3. Hitung relevansi

Tanpa membaca seluruh tabel.


Contoh Full-Text Index di Database #

MySQL / MariaDB #

ALTER TABLE articles
ADD FULLTEXT INDEX ft_content (title, content);

Query:

SELECT *
FROM articles
WHERE MATCH(title, content)
AGAINST('database index' IN NATURAL LANGUAGE MODE);

PostgreSQL (FTS) #

PostgreSQL menggunakan tsvector dan tsquery:

CREATE INDEX idx_articles_fts
ON articles USING GIN(to_tsvector('english', content));

Query:

SELECT *
FROM articles
WHERE to_tsvector('english', content)
@@ to_tsquery('database & index');

Kenapa Full-Text Index Bisa Sangat Mempengaruhi Database? #

Index Size Bisa Sangat Besar #

Full-Text Index:

  • Menyimpan setiap kata
  • Menyimpan mapping kata → row

Akibatnya:

  • Ukuran index bisa lebih besar dari tabel utama
  • Membebani disk dan memory

Cost Tinggi Saat INSERT / UPDATE #

Setiap kali data berubah:

  • Tokenisasi ulang teks
  • Update inverted index

Efeknya:

  • INSERT lebih lambat
  • UPDATE kolom teks lebih mahal

Terutama pada kolom:

  • artikel panjang
  • deskripsi besar
  • log

Ranking & Relevansi Itu Mahal #

Full-Text Index tidak hanya mencari data, tapi juga:

  • Menghitung relevansi
  • Memberi score
  • Sorting hasil

Query ini:

ORDER BY MATCH(content) AGAINST('keyword') DESC

Lebih mahal dibanding query equality biasa.

Bisa Menghasilkan Result Set Besar #

Keyword umum seperti:

  • “data”
  • “system”
  • “user”

Bisa menghasilkan:

  • Ribuan row
  • Transfer network besar
  • Bottleneck di layer aplikasi

Kesalahan Umum Penggunaan Full-Text Index #

❌ Menganggap Full-Text Index Sebagai Solusi Segalanya #

Full-Text Index bukan pengganti:

  • filter by status
  • filter by tenant
  • filter by date

Query buruk:

SELECT *
FROM articles
WHERE MATCH(content) AGAINST('database');

Tanpa filter lain → result besar.

❌ Tidak Menggabungkan Dengan Filter Biasa #

Seharusnya:

SELECT *
FROM articles
WHERE status = 'published'
AND MATCH(content) AGAINST('database');

Filter non-FTI membantu memperkecil search space.

❌ Index Full-Text di Semua Kolom #

Mengindex:

  • title
  • content
  • notes
  • metadata

Sekaligus → index membengkak dan update mahal.


Best Practice Optimasi Full-Text Index #

Gunakan Full-Text Index Hanya untuk Kolom yang Tepat #

Ideal:

  • article content
  • product description

Hindari:

  • kolom kecil
  • kolom yang sering berubah

Selalu Kombinasikan Dengan Filter Lain #

WHERE tenant_id = ?
AND status = 'active'
AND MATCH(content) AGAINST(?);

Tujuan:

  • Perkecil kandidat row
  • Kurangi cost ranking

Batasi Result dengan LIMIT #

ORDER BY relevance DESC
LIMIT 20;

FTI tanpa LIMIT adalah undangan masalah.

Gunakan Mode yang Tepat #

MySQL:

  • NATURAL LANGUAGE MODE
  • BOOLEAN MODE

Gunakan BOOLEAN MODE jika:

  • ingin kontrol kata wajib (+word)
  • ingin exclude (-word)

Jangan Takut Pisahkan Search ke Engine Khusus #

Jika:

  • data sangat besar
  • search sangat kompleks
  • traffic tinggi

Pertimbangkan:

  • Elasticsearch
  • OpenSearch
  • Meilisearch

Database utama tetap fokus pada:

  • transaksi
  • konsistensi

Kesimpulan #

Full-Text Index adalah:

  • Sangat cepat untuk pencarian teks
  • Sangat mahal jika disalahgunakan

Gunakan jika:

  • Memang butuh search teks
  • Sudah dipadukan dengan filter lain
  • Result dibatasi

Hindari jika:

  • Sekadar ingin LIKE '%keyword%'
  • Data kecil
  • Query jarang dipakai

Full-Text Index bukan sekadar index — ia adalah subsystem search mini di dalam database.

Gunakan dengan sadar, bukan refleks.

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact