# pgvector: векторний пошук прямо в PostgreSQL

> Встановлення pgvector для PostgreSQL: створення векторної колонки, індекс HNSW, пошук найближчих сусідів і типові помилки налаштування на VDS.

## Що таке pgvector і коли він потрібен

pgvector — розширення PostgreSQL, яке додає тип даних для векторів та оператори пошуку найближчих сусідів прямо у звичайну базу. Не потрібно піднімати окремий сервіс: вектори зберігаються в тій самій таблиці, що й решта даних, а пошук виконується звичайним SQL-запитом.

Розширення добре підходить проєктам, де PostgreSQL уже використовується як основна база: інтернет-магазину, базі знань, CRM. Для каталогів на десятки мільйонів записів з високим навантаженням на пошук варто порівняти pgvector зі спеціалізованими базами — див. статтю [порівняння векторних баз даних](https://www.zevshost.net/uk/kb/vektornye-bd-sravnenie/).

## Встановлення розширення на 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 — докладніше про вибір моделі і генерацію векторів розказано у статті [семантичний пошук на ембеддингах](https://www.zevshost.net/uk/kb/semanticheskiy-poisk-embeddings/).

## Індекс для швидкого пошуку найближчих сусідів

Без індексу 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.

---

Джерело: https://www.zevshost.net/uk/kb/pgvector-postgresql/
