PunchOndo: Police arrest suspected producer of killer herbal drinksRTP DesportoBenfica reencontra Amorim em Milão e Torreense faz estreia europeiaThe Jerusalem PostIranian nuclear chief blocked from IAEA conference in Vienna following US pressure - reportESPNTransfer rumors, news: Arsenal keeping tabs on Liverpool teen Ngumohaוואלה"הדברים הללו שקריים לחלוטין" | תגובת דובר צה"ל באנגלית לסרט "נז"א"CNN Türkİngiltere’de Hull City rüzgarı: Premier Lig'de kalıcı olacağını gösterdiInquirerPCG searches for fisherman after boat found burning off BatangasDaily MaverickFoot in mouth — politicians talk sh#t while South Africans live in itХабрJava 27: Новый день или Обзор JEP JDK 27SCMP ChinaChina’s self-powered neural device helps stroke survivors walk naturallySky TG24Etna, eruzione e nube di cenere: allerta all'aeroporto di Catania01net6,89 kWh/100 km sur 1 278 km : le nouveau missile de Volkswagen bat un record du monde électrique
The Daily Newsstand · Free, Always
Monday, September 14, 2026

Tarantool против Qdrant и pgvector: честный эксперимент на 1,18 млн векторов

Translate

Многие СУБД сегодня поддерживают поиск ближайших соседей, нужный для рекомендательных систем и антифрода. Но на практике системы даже с одинаковым алгоритмом «под капотом» могут решать эту задачу с разной эффективностью: пропускная способность (QPS) и задержки могут сильно различаться из-за накладных расходов движка хранения и модели блокировок. И для бизнеса эта разница может обернуться лишними затратами на инфраструктуру или деградацией UX в пиковые часы. Поэтому к этим параметрам нередко предъявляются особые требования. 

Привет, Хабр. Меня зовут Георгий Белянин. В статье я разберу архитектуру векторного поиска в Tarantool и приведу результаты сравнения скорости вставки и запросов с Qdrant и pgvector.

Реализация векторного поиска в Tarantool

В последние годы векторный поиск стал одной из базовых технологий для работы с эмбенддингами. Но современные модели создают векторы размерностью в тысячи измерений, поэтому привычные, классические многомерные индексы не всегда способны эффективно справляться с поставленными задачами.

Исходя из этого мы решили совершенствовать возможности Tarantool — он уже поддерживал многомерный поиск через R-tree, но мы задались вопросом добавления современного ANN-индекса (Approximate Nearest Neighbor, алгоритм приближенного поиска соседей), рассчитанного именно работу с высокоразмерными векторами. И поскольку Tarantool — in-memory OLTP-система с движком memtx, где данные лежат прямо в оперативной памяти, наша гипотеза заключалась в том, что при совмещении быстрого in-memory движка с алгоритмом приближенного поиска соседей можно будет получить современный векторный индекс.

Для своей реализации мы рассматривали несколько вариантов алгоритмов приближенного поиска. 

Первая мысль — R-деревья, которые в Tarantool уже есть (R+-tree, R*-tree). R-дерево — это, по сути, многомерное B-дерево: объекты в пространстве ограничиваются «квадратиками» (bounding box), которые объединяются в иерархию. Для OLTP-нагрузок это работает хорошо, но у подхода есть жесткий потолок — приемлемые размерности до ~20 (classic curse of dimensionality). Но нюанс в том, что эмбеддинги современных LLM — это обычно 384, 768, 1024 или 1536 измерений (модели вроде BERT, OpenAI text-embedding и их аналогов). R-дерево на такой размерности просто разваливается.

Далее мы рассмотрели Locality-Sensitive Hashing. Он неплохо сравнивает соседей, распределяя близкие ключи по одним и тем же хеш-бакетам. Но для ANN с требуемым recall в высокой размерности этого недостаточно.

После перешли к изучению HNSW (Hierarchical Navigable Small World). По сути, это многомерный skip-лист: несколько слоев (Layer 0, 1, 2…), переход между которыми дает сначала грубое приближение ответа с большим шагом, а затем итеративное уточнение по мере спуска на нижние уровни. Это не точный поиск, а аппроксимация — но по факту это почти state of the art для ANN-поиска. 

В итоге мы остановились на последнем варианте и реализовали архитектуру, в основе которой три компонента:

  • memtx — самый отлаженный и простой движок Tarantool, данные хранятся построчно в памяти;

  • USearch — легковесная библиотека для HNSW-индексов (ее, например, использует ClickHouse);

  • векторный индекс, который подключается через нативный интерфейс Tarantool: указывается размерность, поле, по которому строится индекс, — и дальше это обычный индекс, как любой другой в системе.

Примечание: Индекс написан на C. Поиск — однопоточный.

Сравнение с альтернативными подходами

Мы понимали, что в других решениях для векторного поиска применены другие подходы. Например:

Хранение

Sharding

API

Плюс

Минус

Qdrant

RAM + DISK

manual

REST / gRPC

Metadata filtering

Нет транзакций, тяжело тюнить HNSW, не KV/SQL

Milvus

RAM + DISK

auto

REST / SDK

Multiple ANN, GPU

Тяжелый кластер, overkill для малых систем

pgvector

RAM + DISK

manual

Это просто Postgres

Не такой шустрый

ClickHouse

RAM + DISK

auto

Быстрый exact match, OLAP

Тяжело с большим write

Redis

RAM

auto

REDIS / REST

Low-latency

Тяжело тюнить индексы

И здесь стоит погрузиться еще в некоторые детали. 

Так, pgvector расширяет синтаксис SQL и добавляет операторы, соответствующие различным метрикам расстояния. Например, оператор <-> используется для вычисления евклидова расстояния между двумя векторами.


Создавайте решения на Tarantool

Ускоряйте цифровые сервисы и снижайте нагрузку на сore‑системы

Получить консультацию


Таким образом, чтобы найти 10 ближайших векторов к заданному, можно воспользоваться следующим SELECT:

SELECT
    id,
    content,
    embedding <-> '[0.1, 0.2, ...]' AS distance
FROM documents
ORDER BY distance
LIMIT 10;

Похожим образом запрос можно сформировать и для ClickHouse. Но в отличие от pgvector, здесь вместо бинарных операторов используются встроенные функции:

SELECT
    id,
    content,
    L2Distance(embedding, [0.1, 0.2, ...]) AS distance
FROM documents
ORDER BY distance
LIMIT 10;

С Qdrant чаще работают через REST API или gRPC, поэтому поиск 10 ближайших соседей выглядит как запрос к определенному эндпойнту:

POST /collections/documents/points/search
Content-Type: application/json
{
    "vector": [0.1, 0.2, ...],
    "limit": 10,
    "with_payload": true
}

При этом в Tarantool чаще всего использует Lua в качестве языка запросов и языка хранимых процедур. Поэтому аналогичный ANN-поиск выполняется с помощью вызова метода индекса векторного типа:

box.space.documents.index.norm:select(
    {1.0, 2.0, ...},
    {
        iterator = 'neighbor',
        limit = 10
    }
)

То есть Tarantool занимает свою нишу.

Понимая это, мы решили оценить, насколько наша реализация верна и сопоставима по основным параметрам с наиболее распространенными технологиями: Qdrant и pgvector.

Для проведения эксперимента мы взяли за основу официальный бенчмарк от Qdrant и адаптировали его под Tarantool — научили загружать те же батчи данных, что и в остальные системы, чтобы сравнение было честным.

Замеры делали на двух датасетах:

  • dbpedia-openai-100K-1536-angular — 100 тысяч векторов, 1536 измерений (акцент на размерности);

  • glove-100 — 1,18 млн векторов, 100 измерений (акцент на количестве).

Все тестировалось in-memory. Метрика на поиске — it/s (queries per second). Индексы у всех участников настраивались одинаково, поэтому и точность (recall) получилась сопоставимая.

Результаты эксперимента

Результаты замеров показали следующее:

  • На датасете с высокой размерностью (100K, dim=1536) Tarantool показал 196 it/s против 176 it/s у Qdrant (+11%) и 82 it/s у pgvector (в 2,4 раза быстрее);

  • На датасете с большим числом векторов (1,18M, dim=100) Tarantool показал 800 it/s против 532 it/s у Qdrant и всего 86 it/s у pgvector. Это +50% к Qdrant и почти в 9,3 раза быстрее pgvector.

Такой результат связан с тем, что у Tarantool данные целиком находятся в оперативной памяти, а быстрый HNSW-индекс дополняется шустрым low-latency OLTP-движком. В итоге Tarantool легко проводит разнородные вычисления, а на большом числе векторов этот эффект масштабируется сильнее, чем на большой размерности одного вектора.

А вот со вставкой все наоборот:

  • На 100K векторов, 1536 измерений — 43 секунды у Tarantool против 19 у Qdrant (в 2,3 раза дольше) и 21 у pgvector (в 2 раза дольше).

  • На 1,18M векторов Tarantool грузит данные 150 секунд — против 57 у Qdrant (в 2,6 раза дольше) и 55 у pgvector (в 2,7 раза дольше).

Такие показатели Tarantool в подобных задачах обусловлены использованием библиотеки USearch, которая показывает тяжеловесную вставку. В итоге на добавление записи и перестройку индекса уходит заметно больше времени, чем у конкурентов.

Но в целом логика здесь тоже объяснимая: если упростить вставку (как это делают Qdrant и pgvector), то платить приходится на чтении — за счет того, что приходится сканировать. Tarantool выбрал обратный компромисс: тяжелая вставка ради быстрого скана.

Примечание: Репозиторий с реализацией доступен на GitHub, поэтому при желании эксперимент можно воспроизвести или использовать как отправную точку для собственных тестов.

Краткое послесловие

Проведенное исследование предсказуемо показало, что наша реализация — не «серебряная пуля» и не подходит для ситуаций, когда критична быстрая массовая загрузка данных или требуется частая актуализация векторов. Вместе с тем наш подход дает ощутимый выигрыш там, где на первый план выходит скорость поиска и тесная интеграция с транзакционной логикой.

И здесь кроется важный инсайт: результаты тестов подтвердили, что для ряда задач совсем не обязательно разворачивать отдельную векторную БД — зачастую для хранения векторов и бизнес‑данных вполне можно ограничиться одной системой, такой как Tarantool, сохранив при этом целостность операций и упростив общую архитектуру.

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.