~/tools / Embedding dan pencarian (RAG) / pgvector SQL Builder

pgvector SQL Builder — Tulis SQL pgvector: tabel, indeks HNSW/IVFFlat, dan kueri nearest neighbor

Tulis SQL untuk menyimpan dan mencari embedding di PostgreSQL dengan pgvector: tabel dengan kolom vector(n) atau halfvec(n), indeks HNSW atau IVFFlat dengan operator class yang sesuai dengan jarak Anda, dan kueri nearest neighbor dengan skor yang mudah dibaca. Alat ini memeriksa batasan yang tercantum dalam dokumentasi pgvector dan memperkirakan ruang yang dipakai vektor. Tidak ada yang keluar dari browser Anda.

Setiap vektor memakai 1,544 byte, jadi 10,000 baris memakai sekitar 15.4 MB untuk vektornya saja (indeks dan kolom lain tidak termasuk).

1. Ekstensi dan tabel

CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE documents (
  id bigserial PRIMARY KEY,
  content text NOT NULL,
  embedding vector(384) NOT NULL
);

2. Indeks

CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);

3. Pencarian

PREPARE menerima vektor pertanyaan dari /api/embed sebagai $1. Kirimkan sebagai teks, seperti '[0.01,-0.02,…]'.

PREPARE search_documents(vector(384)) AS
  SELECT id, content, 1 - (embedding <=> $1) AS cosine_similarity
  FROM documents
  ORDER BY embedding <=> $1
  LIMIT 5;

-- EXECUTE search_documents('[0.0123, -0.0456, ...]');

Batasan dan nilai default dari README dan kode sumber pgvector 0.8.7, diperiksa pada 2026-11-04. pgvector README

Semuanya dilakukan di browser Anda. Alat ini menulis SQL dan tidak terhubung ke mana pun.

pgvector adalah ekstensi open source yang menambahkan pencarian kemiripan vektor ke PostgreSQL, sehingga embedding yang Anda buat dengan Ollama dapat disimpan di database yang sama dengan data Anda yang lain. Ada beberapa detail yang mudah keliru. Kolom harus memiliki jumlah dimensi yang sama dengan model embedding Anda. Setiap jarak punya operatornya sendiri: <=> untuk jarak kosinus, <-> untuk jarak L2, <#> untuk inner product negatif, dan <+> untuk jarak L1. Indeks aproksimasi hanya dipakai jika dibuat dengan operator class untuk jarak yang sama, seperti vector_cosine_ops untuk <=>, dan jika kueri mengurutkan berdasarkan operator itu sendiri secara menaik dengan LIMIT. Alat ini menulis tiga bagian dari satu set pilihan: CREATE EXTENSION dan CREATE TABLE, CREATE INDEX, dan pernyataan PREPARE yang mengembalikan baris terdekat dengan skor yang mudah dibaca (kemiripan kosinus adalah 1 dikurangi jarak kosinus, dan inner product adalah <#> dikalikan -1). Alat ini menerapkan batasan dari README dan kode sumber pgvector versi 0.8.7: hingga 16,000 dimensi dalam satu kolom, indeks hingga 2,000 dimensi untuk vector dan 4,000 untuk halfvec, tidak ada operator class L1 untuk IVFFlat, m HNSW dari 2 sampai 100, dan ef_construction dari 4 sampai 1,000 serta minimal 2 × m. Dengan HNSW, sebuah pencarian mengembalikan paling banyak hnsw.ef_search baris (40 secara default), sehingga alat ini memberi peringatan jika LIMIT lebih besar. Untuk IVFFlat, alat ini mengisi lists dan probes dari titik awal di README: rows / 1000 hingga 1M baris, sqrt(rows) di atas itu, dan sqrt(lists) untuk probes. SQL yang dihasilkan dijalankan pada pgvector 0.8.7 dengan PostgreSQL 16 memakai vektor 384 dimensi asli dari Ollama, dan EXPLAIN menunjukkan indeks dipakai.

Logika utama alat ini bersifat sumber terbuka dengan lisensi MIT. github.com/seigo5555/toolkitbox-lib/src/pgvector-sql.ts

Kapan dipakai

  • Buat tabel untuk chunk dokumen Anda sebelum memuat embedding dari Ollama ke PostgreSQL
  • Periksa operator mana yang berpasangan dengan operator class mana untuk jarak kosinus, L2, inner product, atau L1, agar indeks benar-benar dipakai
  • Perkirakan ruang yang dipakai vektor pada VPS kecil, dan bandingkan vector dengan halfvec

Cara pakai

  1. Masukkan nama tabel dan jumlah dimensi model embedding Anda. Ini adalah panjang satu vektor dari /api/embed; Embedding Similarity Calculator di situs ini menampilkannya.
  2. Pilih tipe, jarak, dan indeks. Dokumentasi Ollama merekomendasikan kemiripan kosinus untuk sebagian besar pencarian semantik, dan /api/embed mengembalikan vektor dengan panjang 1.
  3. Salin ketiga blok dan jalankan di psql atau klien lain. Buat indeks IVFFlat setelah data dimuat; indeks HNSW dapat dibuat pada tabel kosong.

Tanya jawab

Jarak mana yang sebaiknya saya pilih?

Dokumentasi embedding Ollama merekomendasikan kemiripan kosinus untuk sebagian besar kasus pencarian semantik. Di pgvector, <=> mengembalikan jarak kosinus, dan alat ini mengubahnya menjadi cosine_similarity dengan 1 dikurangi jarak tersebut. Untuk vektor dengan panjang 1, seperti yang dari /api/embed, jarak kosinus, jarak L2, dan inner product mengurutkan baris dengan urutan yang sama, karena untuk vektor seperti itu kuadrat jarak L2 sama dengan 2 dikurangi 2 kali kemiripan kosinus.

HNSW atau IVFFlat?

README pgvector mengatakan HNSW punya performa kueri yang lebih baik daripada IVFFlat (dari sisi tradeoff kecepatan-recall) tetapi pembuatannya lebih lambat dan memakai lebih banyak memori, dan dapat dibuat pada tabel kosong karena tidak ada langkah pelatihan. IVFFlat dibuat lebih cepat dan memakai lebih sedikit memori, dan sebaiknya dibuat setelah tabel berisi sejumlah data. Tanpa indeks, pgvector melakukan pencarian eksak, yang memberi recall sempurna.

Mengapa kueri saya tidak memakai indeks?

README mengatakan kueri memerlukan ORDER BY dan LIMIT, dan ORDER BY harus berupa operator jarak itu sendiri dengan urutan menaik, bukan ekspresi seperti 1 - (embedding <=> …) DESC. Operatornya juga harus cocok dengan operator class indeks: <=> dengan vector_cosine_ops, <-> dengan vector_l2_ops, <#> dengan vector_ip_ops, dan <+> dengan vector_l1_ops. Alat ini menulis keduanya dari pilihan yang sama. README juga mencatat bahwa pemindaian tabel mungkin lebih cepat ketika tabelnya kecil.

Mengapa saya mendapat baris lebih sedikit daripada LIMIT?

Dengan HNSW, hasilnya dibatasi oleh hnsw.ef_search, yang secara default 40; ketika kami mencoba LIMIT 100 pada tabel berisi 200 baris, kami mendapat 40 baris sampai kami menaikkan hnsw.ef_search menjadi 100. README menambahkan bahwa pemfilteran dengan WHERE diterapkan setelah indeks dipindai, sehingga suatu kondisi bisa menyisakan baris yang lebih sedikit lagi. Sejak versi 0.8.0, pemindaian indeks iteratif (SET hnsw.iterative_scan = strict_order atau relaxed_order) memindai lebih banyak indeks bila diperlukan.

Apa itu halfvec?

Tipe vektor setengah presisi. Setiap vektor memakai 2 × dimensi + 8 byte, bukan 4 × dimensi + 8, dan indeks HNSW dan IVFFlat pada halfvec mendukung hingga 4,000 dimensi, bukan 2,000. Setiap elemen adalah bilangan floating-point setengah presisi, sehingga nilainya disimpan dengan presisi yang lebih rendah.

Apakah data saya dikirim ke suatu tempat?

Tidak. Alat ini hanya menulis SQL di browser Anda dan tidak pernah terhubung ke database.

Artikel terkait

Terkait