pgvector w praktyce: wyszukiwanie semantyczne bez osobnej bazy wektorowej
Zespół HostBase
Osobna baza wektorowa to kolejna usługa do opłacenia, synchronizacji i zabezpieczenia. Dla większości aplikacji pgvector w Postgresie jest wystarczająco szybki — a wektory leżą obok danych, które opisują, z tymi samymi politykami RLS.
Schemat
create extension if not exists vector;
create table articles (
id bigint generated always as identity primary key,
title text not null,
body text not null,
embedding vector(1024)
);
create index articles_embedding_idx
on articles using hnsw (embedding vector_cosine_ops)
with (m = 16, ef_construction = 64);
Wyszukiwanie
create or replace function search_articles(q vector(1024), k int default 5)
returns table (id bigint, title text, score float)
language sql stable as $$
select id, title, 1 - (embedding <=> q) as score
from articles
order by embedding <=> q
limit k;
$$;
const { data } = await supabase.rpc("search_articles", {
q: await embed("jak zwrócić towar?"),
k: 5,
});
Wyszukiwanie hybrydowe
Najlepsze wyniki daje połączenie wyszukiwania pełnotekstowego i wektorowego. Postgres ma oba — wystarczy połączyć rankingi, np. metodą Reciprocal Rank Fusion.
alter table articles add column fts tsvector
generated always as (to_tsvector('simple', title || ' ' || body)) stored;
create index on articles using gin (fts);
Wskazówki wydajnościowe
- Indeks HNSW buduj po załadowaniu danych — jest to znacznie szybsze.
- Zwiększ
maintenance_work_memna czas budowy indeksu. - Parametr
hnsw.ef_search(domyślnie 40) reguluje kompromis między dokładnością a szybkością. - Mniejsze wymiary (512–1024) często dają podobną jakość przy połowie pamięci.
Więcej w dokumentacji: Wektory i AI.