Що таке pgvector і коли він потрібен
pgvector — розширення PostgreSQL, яке додає тип даних для векторів та оператори пошуку найближчих сусідів прямо у звичайну базу. Не потрібно піднімати окремий сервіс: вектори зберігаються в тій самій таблиці, що й решта даних, а пошук виконується звичайним SQL-запитом.
Розширення добре підходить проєктам, де PostgreSQL уже використовується як основна база: інтернет-магазину, базі знань, CRM. Для каталогів на десятки мільйонів записів з високим навантаженням на пошук варто порівняти pgvector зі спеціалізованими базами — див. статтю порівняння векторних баз даних.
Встановлення розширення на VDS
pgvector встановлюється як звичайне розширення PostgreSQL — з пакетів дистрибутива або збіркою з вихідного коду.
sudo apt update
sudo apt install -y postgresql-16-pgvector
sudo -u postgres psql -d mydb -c "CREATE EXTENSION IF NOT EXISTS vector;"
Якщо пакета немає в репозиторії дистрибутива, розширення збирається з вихідного коду: клонуйте репозиторій проєкту, виконайте make та make install зі встановленими заголовками PostgreSQL.
Створення таблиці з векторною колонкою
Колонка типу vector вимагає вказати розмірність — вона має збігатися з моделлю ембеддингів, яка генерує вектори.
CREATE TABLE articles (
id serial PRIMARY KEY,
title text,
embedding vector(768)
);
Розмірність 768 підходить для моделі multilingual-e5-base — докладніше про вибір моделі і генерацію векторів розказано у статті семантичний пошук на ембеддингах.
Індекс для швидкого пошуку найближчих сусідів
Без індексу PostgreSQL порівнює запит з кожним рядком таблиці — це працює, але повільно зростає з обсягом даних. Індекс HNSW пришвидшує пошук на великих таблицях ціною невеликої похибки.
| Індекс | Точність | Швидкість на 1 млн рядків | Коли застосовувати |
|---|---|---|---|
| Без індексу | 100 % | повільно | таблиці до 10 тисяч рядків |
| IVFFlat | висока | швидко | середні таблиці, рідкісні вставки |
| HNSW | висока | дуже швидко | великі таблиці, часті вставки |
CREATE INDEX ON articles USING hnsw (embedding vector_cosine_ops);
Оператор vector_cosine_ops задає метрику подібності — для нормалізованих ембеддингів косинусна відстань зазвичай дає кращий результат, ніж евклідова.
Пошук найближчих статей за запитом
Після побудови індексу пошук найближчих записів виконується звичайним SELECT з оператором відстані <=>.
SELECT id, title, embedding <=> '[0.12, 0.05, ...]' AS distance
FROM articles
ORDER BY distance
LIMIT 5;
Вектор запиту підставляє застосунок після розрахунку тією самою моделлю, що використовувалася під час індексації. Результат сортується за зростанням відстані — що менше значення, то ближча стаття за змістом до запиту.
Типові помилки налаштування pgvector
Більшість проблем пов'язані з невідповідністю параметрів, а не із самим розширенням:
- Розмірність колонки не збігається з розмірністю моделі — PostgreSQL поверне помилку під час вставки, перевірте вивід моделі заздалегідь.
- Індекс побудований під евклідову відстань, а запити використовують косинусну — результати пошуку виявляться випадковими.
- HNSW створено до масового завантаження даних — індекс краще будувати після первинного імпорту, інакше вставка стане помітно повільнішою.
- Вектори не нормалізовані перед збереженням, хоча модель цього вимагає — звірте прапорець normalize_embeddings у коді генерації.
Після налаштування pgvector дає повноцінний семантичний пошук без додаткового сервісу. Для навантажених проєктів варто виміряти швидкість на реальних даних і порівняти з окремою векторною базою на кшталт Qdrant.