Vector Databases (Pinecone, pgvector) — AI Web

Vector Databases Vector database dirancang untuk menyimpan dan mencari embedding dengan cepat. Database biasa tidak bisa melakukan nearest-neighbor search…

Vector database adalah tempat menyimpan vector (embedding) yang bisa mencari "yang paling dekat" dengan cepat, bahkan di jutaan baris. Bayangin perpustakaan. Kalau bukunya 4, kamu cukup melihat semuanya satu per satu. Kalau bukunya sejuta, kamu butuh katalog yang mengelompokkan buku per rak, lalu cuma memeriksa beberapa rak terdekat. Lebih cepat, tapi sesekali buku terbaik ada di rak sebelah yang gak kamu buka. Itu inti pelajaran ini: exact (periksa semua) lawan approximate (periksa sebagian).

🧪 Tebakan cepat: Toko Buku punya 4 buku, masing-masing dengan vector 1.536 angka. Perlu vector database untuk mencarinya? Tebak dulu, jawabannya ada di bagian "Kapan array di memori sudah cukup".

Kapan array di memori sudah cukup

Exact search membandingkan pertanyaan dengan semua vector, lalu mengambil yang terdekat. Hasilnya pasti benar. Kerjanya: 4 buku × 1.536 angka = 6.144 perkalian per pertanyaan, sepele bagi server mana pun. Jadi gak, Toko Buku belum perlu vector database: array di memori atau kolom JSON (seperti di pelajaran Semantic Search) sudah cukup. Itu jawaban tebakannya.

Kerja exact search naik lurus dengan jumlah baris: 10.000 buku sudah 15,4 juta perkalian per pertanyaan, sejuta buku 1,5 miliar. Di titik itu kamu butuh dua hal: penyimpanan yang ikut transaksi database-mu, dan index yang gak memeriksa semua baris.

pgvector: vector di dalam Postgres

Kalau datamu sudah di PostgreSQL, extension pgvector menambahkan tipe vector dan pencarian nearest-neighbor. Versi terbarunya 0.8.7, rilis 1 Oktober 2026 (dicek di repo GitHub pgvector).

CREATE EXTENSION vector;

ALTER TABLE books ADD COLUMN embedding vector(1536); -- text-embedding-3-small

UPDATE books SET embedding = '[0.021, -0.013, ...]' WHERE id = 4; -- 1.536 angka dari API

SELECT id, title, (embedding <#> $1) * -1 AS kemiripan
FROM books
ORDER BY embedding <#> $1
LIMIT 10;

Operator jarak: <->, <=>, <#>

Operator Artinya Makin kecil berarti
<-> jarak L2 (garis lurus) makin dekat
<=> jarak cosine = 1 − cosine similarity makin mirip
<#> inner product negatif (dot product dikali −1) makin mirip

Untuk vector yang panjangnya 1, seperti embedding OpenAI, ketiganya memberi urutan yang sama, karena L2² = 2 × (1 − cosine). Contoh dari Lab, untuk 3 tetangga terdekat satu pertanyaan sintetis: <-> 0,9439 / 0,9848 / 0,9871, <=> 0,4455 / 0,4850 / 0,4871, <#> −0,5545 / −0,5150 / −0,5129. Urutannya sama persis. README pgvector menyarankan inner product (<#>) untuk vector yang sudah dinormalisasi karena paling cepat. Ingat tandanya: <#> mengembalikan nilai negatif, jadi kalikan −1 untuk mendapat dot product, dan 1 - (embedding <=> $1) untuk cosine similarity.

Exact lawan approximate: HNSW dan IVFFlat

Index vector membuat pencarian approximate (ANN, approximate nearest neighbor): jauh lebih sedikit kerja, tapi kadang tetangga terdekat yang sebenarnya terlewat. Ukurannya recall@10: dari 10 tetangga yang benar (hasil exact), berapa bagian yang ketemu. pgvector punya dua index:

Index Cara kerja Parameter (default)
HNSW graf berlapis; recall per kecepatan lebih baik, build lebih lambat, memori lebih besar m 16, ef_construction 64; saat query hnsw.ef_search 40
IVFFlat vector dibagi ke lists kelompok, query memeriksa probes kelompok terdekat; build cepat, memori kecil lists (mulai dari baris / 1000 sampai 1 juta baris, √baris di atasnya); saat query ivfflat.probes 1 (mulai dari √lists)
CREATE INDEX ON books USING ivfflat (embedding vector_ip_ops) WITH (lists = 32);
SET ivfflat.probes = 4; -- atau, dengan HNSW: SET hnsw.ef_search = 100;

Lab mengukurnya di 2.000 vector acak 32 dimensi (sintetis, dibuat dengan seed tetap), 20 pertanyaan, IVFFlat versi Lab dengan 32 list:

Cara Perbandingan per pertanyaan Recall@10
Exact 2.000 1,000
IVFFlat, probes 1 93,5 0,535
IVFFlat, probes 4 292,9 0,850
IVFFlat, probes 8 551,2 0,925
IVFFlat, probes 16 1.075,8 0,990

Makin banyak kelompok yang diperiksa, recall naik dan kerjanya juga naik. Itu tawar-menawarnya. Angka recall asli tergantung datamu, jadi ukur sendiri dengan membandingkan hasil index dan hasil exact. Buat index IVFFlat setelah tabel berisi data, karena kelompoknya dihitung dari data yang ada.

Filter metadata: stock > 0 sebelum atau sesudah ANN

Pelanggan cuma mau buku yang ada stoknya: WHERE stock > 0. README pgvector menulis bahwa dengan index approximate, filter dijalankan sesudah index dipindai. Contohnya di README: kalau kondisi cocok dengan 10% baris dan hnsw.ef_search 40, rata-rata cuma 4 baris yang tersisa. Di Lab (9% baris punya stok, 179 dari 2.000):

Cara Hasil dari LIMIT 10 Recall@10 Perbandingan
IVFFlat probes 1, filter sesudah 5,15 0,235 93,5
IVFFlat probes 1, iterative scan 10 0,420 196,2
Filter dulu (index B-tree di stock), lalu exact 10 1,000 179

Iterative index scan (sejak pgvector 0.8.0: SET ivfflat.iterative_scan = relaxed_order; atau SET hnsw.iterative_scan = strict_order;) terus memindai bagian index berikutnya sampai hasilnya cukup. Untuk kondisi yang cuma cocok dengan sedikit baris, README menyarankan mulai dengan index biasa di kolom filternya (CREATE INDEX ON books (stock);): Postgres menyaring dulu, lalu menghitung jarak secara exact untuk baris yang tersisa. Di Lab, itu lebih murah sekaligus lebih tepat.

Database vector khusus

Selain pgvector, ada database yang dibuat khusus untuk vector, misalnya Pinecone (layanan terkelola), serta Weaviate dan Chroma (open source). Bedanya dengan database relasional biasa: mereka dioptimalkan untuk pencarian kemiripan di vector berdimensi tinggi, dengan index seperti HNSW, sedangkan index B-tree di database relasional dibuat untuk nilai yang sama persis atau berurutan. Kalau gak mau mengelola server Postgres sendiri, layanan Postgres terkelola seperti Supabase juga menyediakan pgvector. Urutan memilih untuk Toko Buku: array di memori selama bukunya sedikit, pgvector begitu data dan vector perlu satu tempat, dan database khusus kalau kebutuhanmu memang melebihi itu. Ukur recall dan kecepatan dengan datamu sendiri sebelum pindah.

⚠️ Jebakan yang sering ketemu

TL;DR: Exact search membandingkan semua vector dan selalu benar; untuk 4 buku (6.144 perkalian) array di memori sudah cukup. pgvector (0.8.7, Oktober 2026) menaruh kolom vector(1536) di Postgres; index-nya sampai 2.000 dimensi. Operator: <-> L2, <=> jarak cosine, <#> inner product negatif; untuk vector panjang 1 seperti embedding OpenAI urutannya sama, dan <#> yang paling cepat. Index approximate: HNSW (m 16, ef_construction 64, hnsw.ef_search 40) dan IVFFlat (lists, ivfflat.probes default 1); di Lab, probes 1 memberi recall 0,535 dengan 93,5 perbandingan, probes 16 recall 0,990 dengan 1.075,8, exact 2.000. Filter seperti stock > 0 dijalankan sesudah index dipindai, jadi hasilnya bisa kurang dari LIMIT: pakai iterative scan (sejak 0.8.0) atau filter dulu dengan index B-tree. Vector database khusus (Pinecone, Weaviate, Chroma) dioptimalkan untuk pencarian kemiripan vector berdimensi tinggi; pilih berdasarkan ukuran dan hasil ukur, bukan tren.

Yang akan kamu pelajari