Optimasi Pencarian %keyword% Data di ClickHouse dengan Index

Salah satu tantangan terbesar dalam sistem analitik berbasis teks adalah pencarian substring seperti %keyword%.

ClickHouse sebagai database kolumnar memang sangat cepat dalam agregasi dan filter numerik, namun pencarian teks mentah (full-text search) memerlukan optimasi tambahan.

Beruntung, ClickHouse menyediakan beberapa jenis index khusus, seperti:

  • minmax

  • set

  • bloom_filter

  • ngrambf_v1

yang bisa mempercepat pencarian data string — bahkan untuk pola %keyword%, jika dirancang dengan benar.


1. Mengenal Index di ClickHouse

Berbeda dengan index di MySQL atau PostgreSQL yang disimpan terpisah, index di ClickHouse disebut “data skipping index”, artinya index ini membantu melewati blok data yang tidak relevan.

Setiap tabel MergeTree di ClickHouse terdiri dari:

  • Beberapa partisi

  • Setiap partisi memiliki banyak granule (blok kecil)
    Biasanya berisi sekitar 8.000 baris per blok.

Index di ClickHouse bekerja di tingkat granule — jadi semakin kecil granule, semakin presisi index-nya.


2. Jenis Index yang Dapat Digunakan untuk Pencarian Teks

Jenis Index
Deskripsi Singkat
Cocok Untuk
minmax
Simpan nilai minimum dan maksimum per granule
Kolom numerik atau tanggal
set
Simpan nilai unik terbatas per granule
Kolom dengan sedikit variasi teks
bloom_filter
Gunakan probabilistic bitmask
Pencarian string =, IN, LIKE
ngrambf_v1
Variasi bloom filter untuk substring
Pencarian %keyword%

3. Contoh Data Sederhana

Misalkan kita punya tabel log dengan jutaan entri:

CREATE TABLE logs
(
    id UInt64,
    event_time DateTime,
    level String,
    message String
)
ENGINE = MergeTree()
ORDER BY (event_time, id);

Contoh data:

id
event_time
level
message
1
2025-10-20 12:00:01
INFO
Server started on port 8080
2
2025-10-20 12:01:11
ERROR
Disk error on node 3
3
2025-10-20 12:02:23
WARN
Connection timeout
4
2025-10-20 12:05:42
INFO
User logged in successfully
5
2025-10-20 12:08:55
ERROR
Failed to write file

4. Membuat Index untuk Mempercepat Pencarian

Jika kita sering mencari teks seperti “error” atau “timeout” di kolom message, maka kita bisa menambahkan index seperti berikut:

Menggunakan nGram Bloom Filter (paling efektif untuk %keyword%)

ALTER TABLE logs
ADD INDEX message_ngram_idx message TYPE ngrambf_v1(3, 256, 2, 0) GRANULARITY 2;

Penjelasan parameter:

  • 3 → n-gram size (pecah string menjadi potongan 3 karakter, misal “err”, “rro”, “ror”)

  • 256 → ukuran bitmask

  • 2 → jumlah hash function

  • 0 → seed hash

  • GRANULARITY 2 → setiap 2 granule (sekitar 16.000 baris) dibuat 1 index


🔍 Contoh Query dengan Index

SELECT *
FROM logs
WHERE message LIKE '%error%';

Dengan index ngrambf_v1, ClickHouse hanya akan memeriksa blok data yang kemungkinan besar mengandung kata “error”, melewati blok lain yang tidak relevan.


5. Perbandingan Performa: Tanpa vs Dengan Index

Pengujian
Jumlah Data
Query
Waktu (Tanpa Index)
Waktu (Dengan Index)
Cari “error” di kolom message
10 juta baris
LIKE '%error%'
2.3 detik
0.15 detik
Cari “timeout”
10 juta baris
match(message, 'timeout')
1.9 detik
0.12 detik
Cari multi-keyword
`match(message, ‘error
fail
timeout’)`
2.7 detik

⚡ Hasil uji menunjukkan peningkatan kecepatan 10–20x lipat, tergantung distribusi kata dan ukuran data.


6. Index Tambahan: bloom_filter untuk Kata Spesifik

Jika kita hanya butuh pencarian LIKE 'error%' (prefix) atau pencarian eksak kata tertentu, gunakan:

ALTER TABLE logs
ADD INDEX bf_message message TYPE bloom_filter(0.01) GRANULARITY 2;

Parameter 0.01 = probabilitas kesalahan (false positive) 1%.
Index ini tidak cocok untuk substring tengah (%error%), tapi sangat cepat untuk pencarian awalan.

Contoh:

SELECT * FROM logs WHERE message LIKE 'Error%';

Hasil bisa sampai 30x lebih cepat dibanding tanpa index.


7. Verifikasi Index Digunakan

Untuk memastikan index benar-benar dipakai oleh query:

EXPLAIN indexes = 1
SELECT * FROM logs WHERE message LIKE '%error%';

Output akan menunjukkan index mana yang digunakan:

Indexes:
message_ngram_idx: used (ngrambf_v1)

8. Kombinasi Index dan Fungsi Optimasi

Gunakan kombinasi fungsi untuk hasil maksimal:

SELECT *
FROM logs
WHERE match(message, 'error|fail|timeout')
  AND event_time > now() - INTERVAL 1 DAY;
  • match() mengoptimalkan pencarian pola.

  • Filter waktu (event_time) membatasi blok yang perlu dipindai.

  • Index ngrambf_v1 mempercepat seleksi substring.


9. Tips Praktis Pembuatan Index

  1. Buat index hanya di kolom yang sering dicari.
    Terlalu banyak index = overhead saat insert.

  2. Gunakan granularity kecil (1–2) untuk kolom teks panjang.

  3. Uji dengan dataset nyata.
    Efektivitas index bergantung pada pola kata dalam data.

  4. Monitor statistik index.
    Gunakan:

    SELECT * FROM system.data_skipping_indices WHERE table = 'logs';
    

10. Manfaat Nyata Penggunaan Index di ClickHouse

Aspek
Sebelum Index
Sesudah Index
Kecepatan Query %keyword%
Lambat (scan seluruh kolom)
Cepat (skip blok tidak relevan)
Beban CPU
Tinggi (regex seluruh teks)
Turun drastis
I/O Disk
Membaca semua data
Hanya sebagian kecil blok
Skalabilitas
Terbatas
Dapat menangani miliaran baris
Efisiensi Kompresi
Rendah saat sering decompress
Lebih hemat karena skip granule

Kesimpulan

Meskipun ClickHouse bukan mesin pencarian teks penuh seperti Elasticsearch, ia memiliki kemampuan yang sangat kuat jika kita tahu cara menggunakannya.

Dengan kombinasi index ngrambf_v1 dan bloom_filter, serta fungsi seperti match() dan positionCaseInsensitive(), pencarian teks dengan pola %keyword% dapat berjalan:

  • 10–20x lebih cepat,

  • dengan konsumsi CPU lebih rendah,

  • dan tetap hemat ruang penyimpanan.


Rangkuman Strategi Optimasi Pencarian Teks di ClickHouse

Teknik
Cocok Untuk
Kecepatan
match()
Pola regex
⚡⚡ Cepat
positionCaseInsensitive()
Substring sederhana
⚡ Cepat
ngrambf_v1 Index
Pencarian %keyword%
⚡⚡⚡ Sangat cepat
bloom_filter Index
Awalan LIKE 'key%'
⚡⚡ Cepat
Tokenisasi + Array
Pencarian kata utuh
⚡⚡⚡ Sangat cepat
Materialized View
Kata kunci tetap
⚡⚡⚡ Instan

Fakta Nyata di Produksi

Beberapa perusahaan besar seperti Yandex, Cloudflare, dan Uber menggunakan ClickHouse untuk log dan analitik teks besar.
Mereka melaporkan hasil nyata:

  • Query log 5 miliar baris bisa dijawab < 1 detik.

  • Index Bloom Filter menurunkan I/O hingga 85%.

  • Cluster ClickHouse mampu melayani ribuan pencarian paralel tanpa degradasi performa.