pgvector: полный обзор
Что pgvector добавляет в PostgreSQL: расстояния, индексы и типы, сравнение с векторными базами, три примера SQL, настройки для рабочего проекта и частые ошибки.
Коротко
pgvector — расширение для PostgreSQL, которое добавляет тип для векторов, операторы расстояния и индексы для быстрого поиска похожего. Оно превращает обычную базу в хранилище для поиска по смыслу, рекомендаций и RAG: векторы живут в той же таблице, что и товары, статьи или обращения, фильтруются обычным SQL, соединяются с другими таблицами и попадают в резервные копии вместе со всем остальным. Большинству проектов — до десятков миллионов векторов — отдельная векторная база не нужна. Расширение есть в основных управляемых сервисах PostgreSQL и ставится на свой сервер одним пакетом.
pgvector коротко
Главные факты одной таблицей: что добавляет расширение и где оно работает.
- Что это
- Расширение PostgreSQL с открытым кодом для хранения векторов и поиска по ним
- История
- Эндрю Кейн, 2021 год; индексы HNSW с версии 0.5 (2023), итеративный поиск с 0.8 (2024)
- Лицензия
- Лицензия PostgreSQL — бесплатно, в том числе для коммерции
- Типы
vector,halfvec(вдвое меньше),sparsevec,bit- Индексы
- HNSW и IVFFlat — приближённый поиск
- Где работает
- Свой сервер, AWS, Google Cloud, Azure, Supabase, Neon и другие сервисы
- Комфортный масштаб
- До десятков миллионов векторов на одном сервере
Расстояния, индексы и типы
Всё, что pgvector добавляет в SQL. Расстояние в запросе должно совпадать с классом операторов индекса, иначе индекс не используется.
| Элемент | Что это | Когда брать |
|---|---|---|
| <=> | косинусное расстояние | эмбеддинги текста — обычный выбор |
| <-> | евклидово расстояние (L2) | картинки, координаты, некоторые модели |
| <#> | отрицательное скалярное произведение | нормированные векторы — быстрее всего |
| <+> | манхэттенское расстояние (L1) | редкие особые случаи |
| HNSW | индекс-граф: быстрый и точный | по умолчанию для большинства проектов |
| IVFFlat | индекс кластеров: меньше, строится быстрее | большие неизменные наборы, после загрузки данных |
| halfvec | векторы половинной точности | вдвое меньше памяти почти без потери качества |
| bit | двоичные векторы с расстоянием Хэмминга | быстрый первый проход по очень большим наборам |
pgvector или отдельная векторная база
Pinecone, Qdrant, Weaviate и Milvus созданы только для векторов. Вот что это даёт и чего стоит.
| Критерий | pgvector | Векторная база |
|---|---|---|
| Где живут векторы | рядом с данными, в той же таблице | в отдельном сервисе |
| Синхронизация | не нужна — одна транзакция | нужна, источник расхождений |
| Фильтры | обычный SQL, соединения | свой язык фильтров |
| Поиск по словам | полнотекстовый поиск PostgreSQL | зависит от продукта |
| Копии и права | те же, что у всей базы | настраиваются отдельно |
| Масштаб | десятки миллионов векторов | до миллиардов |
| Стоимость | ничего сверху | отдельный счёт или серверы |
Как выглядит pgvector: 3 примера
Таблица с индексом, поиск с фильтром и гибридный поиск по смыслу и по словам. Вектор вопроса считает приложение и передаёт параметром.
Таблица и индекс
Вектор — просто ещё одна колонка; индекс HNSW строится под косинусное расстояние.
-- pgvector: векторы живут в обычной таблице рядом с остальными данными
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE products (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
sku text UNIQUE NOT NULL,
title text NOT NULL,
category text NOT NULL,
in_stock boolean NOT NULL DEFAULT true,
embedding vector(1024) -- размер задаёт модель эмбеддингов
);
-- Индекс HNSW для косинусного расстояния: быстрый приближённый поиск
CREATE INDEX products_embedding_idx
ON products USING hnsw (embedding vector_cosine_ops);
Поиск с фильтром
Обычные условия WHERE рядом со сходством; итеративный поиск не даёт выдаче опустеть при строгом фильтре.
-- Похожие товары в наличии; вектор запроса приходит из приложения как $1
SET hnsw.iterative_scan = relaxed_order; -- pgvector 0.8+: искать дальше, пока фильтр отбрасывает строки
SELECT sku, title, 1 - (embedding <=> $1) AS similarity
FROM products
WHERE in_stock AND category = 'tables'
ORDER BY embedding <=> $1
LIMIT 10;
Гибридный поиск
Смысл находит «обеденный стол» по запросу «стол на кухню», слова — точный артикул, вместе — и то и другое.
-- Гибридный поиск: по смыслу (pgvector) и по словам (полнотекстовый поиск),
-- два списка объединяются по местам — Reciprocal Rank Fusion
WITH semantic AS (
SELECT id, row_number() OVER (ORDER BY embedding <=> $1) AS rank
FROM products
ORDER BY embedding <=> $1
LIMIT 20
),
keyword AS (
SELECT id, row_number() OVER (ORDER BY ts_rank_cd(to_tsvector('russian', title), q) DESC) AS rank
FROM products, plainto_tsquery('russian', $2) AS q
WHERE to_tsvector('russian', title) @@ q
ORDER BY ts_rank_cd(to_tsvector('russian', title), q) DESC
LIMIT 20
)
SELECT p.sku, p.title,
coalesce(1.0 / (60 + s.rank), 0) + coalesce(1.0 / (60 + k.rank), 0) AS score
FROM semantic s
FULL OUTER JOIN keyword k ON k.id = s.id
JOIN products p ON p.id = coalesce(s.id, k.id)
ORDER BY score DESC
LIMIT 10;
7 настроек, которые важны в рабочем проекте
-
01
Индекс совпадает с оператором
Индекс на
vector_cosine_opsработает только для<=>; план проверяют через EXPLAIN. -
02
ef_search для точности
hnsw.ef_search(по умолчанию 40) поднимают, когда в выдаче не хватает нужного. -
03
Память на построение
Больший
maintenance_work_memстроит индекс HNSW в разы быстрее. -
04
halfvec для больших наборов
Вдвое уменьшает таблицу и индекс почти без потери качества.
-
05
Итеративный поиск с фильтрами
Без него строгий WHERE может вернуть меньше строк, чем LIMIT.
-
06
Частичные индексы
Отдельный индекс на язык или категорию, когда поиск никогда их не пересекает.
-
07
Одна модель на колонку
Векторы разных моделей несравнимы — новая модель означает новую колонку и переиндексацию.
Частые ошибки с pgvector
-
Отдельная векторная база раньше времени
Ещё один сервис и синхронизация ради нескольких сотен тысяч векторов, которые PostgreSQL держит легко.
-
Нет индекса
Без него каждый запрос сравнивает вопрос со всеми строками — терпимо на тысячах, медленно на миллионах.
-
IVFFlat на пустой таблице
Его кластеры считаются по имеющимся данным; построенный слишком рано, он плохо ищет.
-
Сходство без порога
ORDER BY всегда вернёт ближайшие строки, даже если ни одна не подходит.
-
Смешивать модели
Часть строк проиндексирована одной моделью, часть другой — поиск молча портится.
-
Векторы без исходного текста
Текст хранят рядом с вектором — чтобы показать, процитировать и переиндексировать.
Вопросы о pgvector
Что такое pgvector?
Расширение, которое позволяет PostgreSQL хранить векторы и искать самые похожие.
Сколько векторов он выдержит?
Десятки миллионов на одном сервере с индексом HNSW; дальше — секционирование или специализированная система.
HNSW или IVFFlat?
HNSW в большинстве случаев: он точнее и работает на таблице, которая постоянно меняется.
Какой размер вектора нужен?
Тот, что выдаёт модель эмбеддингов, — 384, 768, 1024, 1536 и так далее.
Есть ли он в управляемом PostgreSQL?
Да, в AWS, Google Cloud, Azure, Supabase, Neon и большинстве других сервисов.
Работает ли он с MySQL?
Нет, это расширение PostgreSQL; у MySQL в последних версиях свой тип для векторов.
Можно ли искать по картинкам?
Да, если картинки превращены в векторы подходящей моделью; базе неважно, что означает вектор.
Форма
Поиск
по смыслу
Делаю поиск по смыслу, рекомендации и ИИ-ассистентов на PostgreSQL с pgvector — рядом с вашими данными, без отдельного сервиса. Расскажите о проекте — отвечу в течение рабочего дня.