Векторные индексы
Внимание
Фукциональность векторных индексов доступна, начиная с версии 25.1.2
.
Для включения векторных индексов необходимо установить значение feature flag enable_vector_index
в true
.
В настоящее время не поддерживается:
- Обновление индекса: модифицировать основную таблицу можно, но существующий индекс не обновится. Нужно построить новый индекс, чтобы учесть изменения. При необходимости, можно атомарно заменить существующий индекс на вновь построенный.
- Построение индекса для векторов c битовым квантованием.
Эти ограничения могут быть устранены в будущих версиях.
Векторные индексы — это специализированные структуры данных, которые позволяют эффективно выполнять векторный поиск в многомерных пространствах. В отличие от вторичных индексов, которые оптимизируют поиск по равенству или диапазону, векторные индексы позволяют выполнять приближенный поиск на основе функций схожести или расстояния.
Данные в таблице YDB хранятся и сортируются по первичному ключу, что обеспечивает эффективный поиск по точному совпадению и сканирование диапазонов. Векторные индексы предоставляют аналогичную эффективность для поиска ближайших соседей в векторных пространствах.
Характеристики векторных индексов
Векторные индексы в YDB решают задачу поиска ближайших соседей с использованием функций схожести или расстояния. Поддерживается несколько функций расстояния/схожести: "inner_product", "cosine" (схожесть) и "cosine", "euclidean", "manhattan" (расстояние).
В текущей реализации доступен один тип индекса: vector_kmeans_tree
.
vector_kmeans_tree
Векторный индекс типа Индекс vector_kmeans_tree
реализует иерархическую кластеризацию данных. Структура индекса включает:
-
Иерархическая кластеризация:
- индекс строит несколько уровней k-means кластеров;
- на каждом уровне векторы распределяются по заданному количеству кластеров в степени уровня;
- первый уровень кластеризует весь набор данных;
- последующие уровни рекурсивно кластеризуют содержимое каждого родительского кластера.
-
Процесс поиска:
- поиск идет рекурсивно от первого уровня к последующим;
- при выполнении запросов индекс анализирует только наиболее перспективные кластеры;
- такое усечение пространства поиска позволяет избежать полного перебора всех векторов.
-
Параметры:
levels
: число уровней в дереве, задает глубину поиска (рекомендуется 1-3);clusters
: количество кластеров в k-means, определяющее ширину поиска (рекомендуется 64-512).
Внутри векторный индекс состоит из скрытых индексных таблиц вида indexImpl*Table
. В запросах на выборку с использованием векторного индекса, индексные таблицы будут отображены в статистике запросов.
Виды векторных индексов
Векторный индекс может быть покрывающим, что означает включение дополнительных колонок для возможности чтения из индекса без обращения к основной таблице.
Или же он может быть с поддержкой фильтрации, что позволяет учитывать дополнительные колонки для быстрой фильтрации при выполнении чтения.
Ниже приведены примеры создания векторного индекса различных типов.
Базовый векторный индекс
Глобальный векторный индекс по колонке embedding
:
ALTER TABLE my_table
ADD INDEX my_index
GLOBAL USING vector_kmeans_tree
ON (embedding)
WITH (distance=cosine, vector_type="uint8", vector_dimension=512, levels=2, clusters=128);
Векторный индекс с покрывающими колонками
Покрывающий векторный индекс, включающий дополнительную колонку data
, чтобы избежать чтения из основной таблицы при поиске:
ALTER TABLE my_table
ADD INDEX my_index
GLOBAL USING vector_kmeans_tree
ON (embedding) COVER (data)
WITH (distance=cosine, vector_type="uint8", vector_dimension=512, levels=2, clusters=128);
Векторный индекс с фильтрацией
Векторный индекс с фильтрацией, позволяющий фильтровать по колонке user
в момент выполнения векторного поиска:
ALTER TABLE my_table
ADD INDEX my_index
GLOBAL USING vector_kmeans_tree
ON (user, embedding)
WITH (distance=cosine, vector_type="uint8", vector_dimension=512, levels=2, clusters=128);
Векторный индекс с фильтрацией и покрывающими колонками
Векторный индекс с фильтрацией и покрывающими колонками:
ALTER TABLE my_table
ADD INDEX my_index
GLOBAL USING vector_kmeans_tree
ON (user, embedding) COVER (data)
WITH (distance=cosine, vector_type="uint8", vector_dimension=512, levels=2, clusters=128);
Создание векторных индексов
Векторные индексы можно создавать:
- при создании таблицы с помощью YQL-оператора CREATE TABLE;
- добавлять к существующей таблице с помощью YQL-оператора ALTER TABLE.
Использование векторных индексов
Запросы к векторным индексам выполняются с использованием синтаксиса VIEW
в YQL:
DECLARE $query_vector AS List<Uint8>;
SELECT user, data
FROM my_table VIEW my_index
ORDER BY Knn::CosineSimilarity(embedding, $query_vector) DESC
LIMIT 10;
Для индексов с фильтрацией укажите соответствующие колонки в условии WHERE
:
DECLARE $query_vector AS List<Uint8>;
SELECT user, data
FROM my_table VIEW my_index
WHERE user = 'john'
ORDER BY Knn::CosineSimilarity(embedding, $query_vector) DESC
LIMIT 10;
Подробнее о выполнении запросов SELECT
с использованием векторных индексов можно прочитать в разделе VIEW VECTOR INDEX.
Примечание
Если не использовать выражение VIEW
, запрос выполнит полное сканирование таблицы с попарным сравнением векторов.
Рекомендуется проверять оптимальность написанного запроса, используя статистику запросов. В частности, следует следить за отсутствием полного сканирования (full scan) основной таблицы.
Рецепты работы с векторным индексом
Для начала работы с векторным индексом можно воспользоваться следующими рецептами: