Управление индексами

Добавление индекса

ADD INDEX — добавляет индекс с указанным именем и типом для заданного набора колонок в строковых таблицах. Грамматика:

ALTER TABLE `<table_name>`
  ADD INDEX `<index_name>`
    [GLOBAL|LOCAL]
    [UNIQUE]
    [SYNC|ASYNC]
    [USING <index_type>]
    ON ( <index_columns> )
    [COVER ( <cover_columns> )]
    [WITH ( <parameter_name> = <parameter_value>[, ...])]
  [,   ...]
  • GLOBAL/LOCAL — глобальный или локальный индекс, в зависимости от типа индекса (<index_type>) может быть доступен только один из них:

    • GLOBAL — индекс, реализованный в виде отдельной таблицы или набора таблиц. Синхронное обновление такого индекса требует распределённых транзакций.
    • LOCAL — локальный индекс в рамках шарда колоночной или строковой таблицы, не требует распределённых транзакций при обновлении, однако не обеспечивает прюнинг при поиске.
  • <index_name> — уникальное имя индекса, по которому будет возможно обращение к данным.

  • SYNC/ASYNC — признак синхронности индекса.

  • UNIQUE — признак уникального вторичного индекса. Уникальный индекс должен быть глобальным синхронным (GLOBAL UNIQUE SYNC) и не должен содержать конструкцию USING <index_type>.

  • <index_type> - тип индекса, в настоящее время поддерживаются:

    • secondary — вторичный индекс. Для вторичных индексов доступен только режим GLOBAL. Это тип индекса по умолчанию.
    • vector_kmeans_tree — векторный индекс. Подробнее описан в разделе Векторный индекс.
    • fulltext_plain — базовый полнотекстовый индекс. Подробнее описан в Полнотекстовый индекс.
    • fulltext_relevance — полнотекстовый индекс со статистикой BM25 для расчёта релевантности. Подробнее описан в Полнотекстовый индекс.
    • json — JSON-индекс для ускорения предикатов JSON_EXISTS и JSON_VALUE по колонке типа Json или JsonDocument. Подробнее описан в JSON-индекс.
    • bloom_filter — локальный Блум-индекс. Доступен только LOCAL. См. ALTER TABLE ADD INDEX.
    • bloom_ngram_filter — локальный N-граммный Блум-индекс. Доступен только LOCAL. См. ALTER TABLE ADD INDEX.
    • min_max — локальный min/max-индекс. Доступен только LOCAL. См. ALTER TABLE ADD INDEX.
  • <index_columns> — список имён колонок создаваемой таблицы через запятую, по которому определяется состав и порядок включения колонок в ключ индекса. Обязательно должен быть указан. Ключ индекса будет состоять из этих колонок с добавлением колонок первичного ключа таблицы.

  • <cover_columns> — список имён колонок создаваемой таблицы через запятую, которые будут сохранены в индексе дополнительно к колонкам ключа индекса, давая возможность получить дополнительные данные без обращения за ними в таблицу. По умолчанию пуст.

  • <parameter_name> и <parameter_value> — параметры индекса, специфичные для конкретного <index_type>. Некоторые параметры индекса нельзя задать при его создании. См. Изменение параметров индекса.

Также добавить вторичный индекс можно с помощью команды table index YDB CLI.

Параметры для всех типов индексов:

  • parallel - максимальное число параллельных обработчиков на основе партиций, задействованных в построении индекса (целое число между 1 и MaxBuildIndexShardsInFlight из SchemeShardConfig).
    • Если параметр не указан, сейчас используется значение по умолчанию 32 или MaxBuildIndexShardsInFlight, если это значение меньше. MaxBuildIndexShardsInFlight по умолчанию равен 1000. В будущих версиях логика выбора параллелизма по умолчанию может быть изменена.
    • Вы можете установить меньший лимит, чтобы снизить влияние построения индекса на производительность базы данных.
    • Вы также можете установить больший лимит, чтобы ускорить построение индекса, если у вас достаточно аппаратных ресурсов.

Параметры, специфичные для векторных индексов:

  • общие параметры для всех векторных индексов:
    • vector_dimension - размерность вектора эмбеддинга (значение от 1 до 65536);
    • vector_type - тип значений вектора (float, float16, bfloat16, uint8, int8 или bit);
    • distance - функция расстояния (cosine, manhattan или euclidean), взаимосключающий с similarity;
    • similarity - функция схожести (inner_product или cosine), взаимосключающий с distance;
  • специфичные параметры для vector_kmeans_tree (подробнее о типе индекса):
    • clusters - количество центроидов для алгоритма k-means (значение от 2 до 2048);
    • levels - количество уровней в дереве (значение от 1 до 16);
    • overlap_clusters - максимальное число ближайших листовых кластеров, в которые добавляется каждый вектор; оно не должно превышать clusters. Если параметр не указан, YDB может автоматически включить перекрытие для больших наборов данных. Если перекрытие не включено, каждый вектор попадает в один кластер;
    • adaptive_clusters - для индексов с фильтрацией автоматически выбирать количество кластеров для каждого значения фильтруемой колонки в зависимости от количества векторов у этого значения (true или false, по умолчанию false; включается при автоматическом подборе параметров). Подробнее см. Адаптивное количество кластеров;
    • общее количество узлов в дереве, рассчитываемое как clusters в степени levels, должно быть не более чем 1073741824;
    • произведение vector_dimension на clusters должно быть не более чем 4194304.

Примечание

Для векторных индексов параметры vector_type и vector_dimension можно не указывать, если таблица не пуста — они определяются автоматически по содержимому строк. Параметры levels и clusters также определяются автоматически, и для них таблица может быть пустой, но делать это крайне не рекоммендуется так как дефолтные значения в этом случае levels=1, clusters=2, гораздо лучше создавать индекс по таблице куда уже загруженны данные, чтобы значения могли правильно определиться.

Параметры, специфичные для полнотекстовых индексов:

  • общие параметры для всех полнотекстовых индексов:
    • analyzer - готовый анализатор: standard (стандартный токенизатор, нижний регистр и удаление английских стоп-слов), snowball (стандартный токенизатор, нижний регистр, удаление стоп-слов и лемматизация Snowball; требуется language) или keyword (весь текст становится одним токеном с сохранением регистра)
    • tokenizer - тип токенизатора (standard, whitespace, alphanumeric или keyword)
    • use_filter_lowercase - фильтр приведения к нижнему регистру (true или false)
    • use_filter_stopwords - удаление частотных слов, например the и and (true или false). Поддерживаются английский и русский языки; если language не указан, используется английский
    • use_filter_length - фильтр по длине токена (true или false); при значении true токены короче filter_length_min или длиннее filter_length_max не индексируются
    • filter_length_min - минимальная длина токена (положительное целое); применяется только при use_filter_length=true
    • filter_length_max - максимальная длина токена (положительное целое); применяется только при use_filter_length=true
    • use_filter_snowball - фильтр лемматизации Snowball (true или false)
    • language - язык или список языков через запятую для лемматизатора Snowball. Пробелы вокруг запятых допустимы, например "english, russian". Готовый анализатор snowball дополнительно удаляет стоп-слова, поэтому вместе с ним можно указать только english и russian
    • use_filter_ngram - фильтр N-грамм (true или false)
    • use_filter_edge_ngram - фильтр краевых N-грамм (true или false)
    • filter_ngram_min_length - минимальная длина N-граммы (положительное целое)
    • filter_ngram_max_length - максимальная длина N-граммы (положительное целое)

Параметры локальных блум-индексов

  • bloom_filter
    • false_positive_probability — целевая вероятность ложноположительного срабатывания фильтра: доля фрагментов, которые фильтр не отсечёт, хотя искомого значения в них нет (диапазон (0, 1)). Меньшее значение уменьшает число лишних чтений, но увеличивает размер индекса.
      • Если параметр не указан, для строковых таблиц используется 0.0001, для колоночных — 0.1. Более строгий порог по умолчанию в строковых таблицах соответствует OLTP-сценарию точечных чтений; в колоночных — аналитическим сканам, где допустим больший компромисс между размером индекса и отсечением фрагментов.
    • Индексируемые колонки — типы YQL, для которых определено сравнение на равенство, кроме Yson, Json и JsonDocument (см. операторы сравнения). В колоночной таблице допускается одна колонка; в строковой — несколько. На строковых таблицах индексируемые колонки должны образовывать левый префикс первичного ключа.
  • bloom_ngram_filter (колонки String, Utf8; только колоночные таблицы)
    • ngram_size — размер n-граммы, целое число от 3 до 8 (по умолчанию 3).
    • false_positive_probability — целевая вероятность ложноположительного срабатывания (диапазон (0, 1); по умолчанию 0.1).
    • case_sensitive — учёт регистра при построении n-грамм: true или false (по умолчанию true).

Параметры локального min_max-индекса

У min_max-индекса нет специфичных параметров WITH (...).

Ограничения

Операция ADD INDEX для создания глобальных вторичных (GLOBAL, UNIQUE и т.п.) и векторных индексов поддерживается только для строковых таблиц. Для колоночных таблиц через ADD INDEX поддерживаются только локальные индексы: блум-индекс и min_max-индекс.

Особенности локальных блум-индексов:

  • Индекс всегда локальный (LOCAL); глобального варианта нет.
  • В запросах не используется синтаксис VIEW <index> (в отличие, например, от полнотекстовых индексов).
  • Фильтр применяется при чтении только к тем фрагментам данных, для которых при записи или слиянии порций уже сохранён блок индекса, для остальных фрагментов пропуск по этому индексу не выполняется.
  • На строковых таблицах bloom_filter реализован как префиксный фильтр Блума: индексируемые колонки должны образовывать левый префикс первичного ключа. Фильтр строится по этому префиксу ключа и ускоряет точечные чтения и сканы по диапазону, ограничивающие префикс. Два индекса bloom_filter с одинаковой длиной префикса не допускаются.

Ограничения

  • Секции COVER (...) и дополнительные колонки индекса не поддерживаются.
  • Для колоночных таблиц индексируемая колонка должна быть одна. Для строковых таблиц допускается несколько индексируемых колонок.
  • Для строковых таблиц тип индекса bloom_ngram_filter не поддерживается.
  • На строковых таблицах индексируемые колонки bloom_filter должны образовывать левый префикс первичного ключа. Наборы колонок, не являющиеся префиксом, отклоняются.
  • На строковых таблицах два индекса bloom_filter не могут иметь одинаковую длину префикса (один и тот же набор ведущих колонок первичного ключа).

Особенности локального min_max-индекса:

  • Индекс всегда локальный (LOCAL); глобального варианта нет.
  • В запросах не используется синтаксис VIEW <index> (в отличие, например, от полнотекстовых индексов).
  • Фильтр применяется при чтении только к тем фрагментам данных, для которых при записи или слиянии уже вычислены и сохранены вместе с данными таблицы минимальное и максимальное значения индексируемой колонки; для остальных фрагментов пропуск по этому индексу не выполняется.

Ограничения

  • Поддерживаются только для колоночных таблиц.
  • В ON (...) должна быть указана ровно одна колонка.
  • COVER (...) и дополнительные колонки данных не поддерживаются.
  • Специфичные параметры WITH (...) не поддерживаются.
  • ALTER INDEX для min_max-индекса не поддерживается.
  • Колонки типов Json и JsonDocument не поддерживаются.

Примеры

Вторичный индекс:

ALTER TABLE `series`
  ADD INDEX `title_index`
  GLOBAL ON (`title`);

Векторный индекс:

ALTER TABLE `series`
  ADD INDEX emb_cosine_idx GLOBAL SYNC USING vector_kmeans_tree
  ON (embedding) COVER (title)
  WITH (
    distance="cosine", vector_type="float", vector_dimension=512
  );

Полнотекстовый индекс:

ALTER TABLE `series`
  ADD INDEX ft_idx GLOBAL USING fulltext_plain
  ON (title)
  WITH (tokenizer=standard, use_filter_lowercase=true);

JSON-индекс:

ALTER TABLE `series`
  ADD INDEX json_idx GLOBAL USING json
  ON (metadata);

Блум-индекс:

ALTER TABLE `/Root/Table`
  ADD INDEX idx_bloom LOCAL USING bloom_filter
  ON (resource_id)
  WITH (false_positive_probability = 0.01);

Блум n-граммный индекс:

ALTER TABLE `/Root/Table`
  ADD INDEX idx_ngram LOCAL USING bloom_ngram_filter
  ON (message)
  WITH (
    ngram_size = 3,
    false_positive_probability = 0.01,
    case_sensitive = true
  );

min_max-индекс:

ALTER TABLE `/Root/Table`
  ADD INDEX idx_created_at LOCAL USING min_max
  ON (created_at);

Изменение параметров индекса

Индексы имеют параметры, зависящие от типа, которые можно настраивать. Глобальные индексы, синхронные или асинхронные, реализованы в виде скрытых таблиц, и их параметры автоматического партиционирования и реплик можно регулировать так же, как и настройки обычных таблиц.

Примечание

В настоящее время задание настроек партиционирования вторичных индексов при создании индекса не поддерживается ни в операторе ALTER TABLE ADD INDEX, ни в операторе CREATE TABLE INDEX.

ALTER TABLE <table_name> ALTER INDEX <index_name> SET <setting_name> <value>;
ALTER TABLE <table_name> ALTER INDEX <index_name> SET (<setting_name_1> = <value_1>, ...);

Примечание

Операция RESET для ALTER INDEX не поддерживается.

  • <value> - новое значение параметра. Возможные значения включают:

    • ENABLED или DISABLED для параметров AUTO_PARTITIONING_BY_SIZE и AUTO_PARTITIONING_BY_LOAD
    • "PER_AZ:<count>" или "ANY_AZ:<count>" где <count> — число реплик для READ_REPLICAS_SETTINGS
    • для остальных параметров — целое число типа Uint64
    • для FALSE_POSITIVE_PROBABILITY — число с плавающей точкой в диапазоне (0, 1); меньшее значение обычно уменьшает число ложноположительных срабатываний, но увеличивает размер индекса
    • для NGRAM_SIZE — целое число в диапазоне от 3 до 8 (обычно рекомендуется начинать с 3)
    • для CASE_SENSITIVE — true или false

Пример

Код из следующего примера включает автоматическое партиционирование по нагрузке для индекса с именем title_index в таблице series, устанавливает минимальное количество партиций равным 5 и запускает по одной реплике в каждой зоне доступности (AZ) для каждой партиции:

ALTER TABLE `series` ALTER INDEX `title_index` SET (
    AUTO_PARTITIONING_BY_LOAD = ENABLED,
    AUTO_PARTITIONING_MIN_PARTITIONS_COUNT = 5,
    READ_REPLICAS_SETTINGS = "PER_AZ:1"
);

Для локальных блум-индексов можно также менять специфичные для них параметры, например:

ALTER TABLE `/Root/Table` ALTER INDEX idx_ngram SET (
    ngram_size = 4,
    false_positive_probability = 0.005,
    case_sensitive = false
);

Перестроение векторного индекса

REBUILD INDEX создаёт новую версию существующего векторного индекса по данным таблицы и атомарно заменяет старый индекс с сохранением имени. Используйте команду для пересчёта кластеров после изменения распределения данных или для изменения параметров кластеризации.

Операция поддерживает только индексы vector_kmeans_tree, включая индексы с фильтрацией и покрывающие индексы. Индекс должен существовать и находиться в состоянии Ready, то есть его предыдущее построение должно быть завершено. Проверить наличие и тип индекса можно командой scheme describe.

Чтобы перестроить индекс с текущими настройками, выполните:

ALTER TABLE `my_table` REBUILD INDEX `my_vector_index`;

Чтобы изменить параметры кластеризации при перестроении, добавьте WITH:

ALTER TABLE `my_table` REBUILD INDEX `my_vector_index`
WITH (clusters = 128, levels = 2);

В WITH можно указать следующие параметры:

Параметр Описание
clusters Количество кластеров. Целое число от 2 до 2048.
levels Количество уровней дерева. Целое число от 1 до 16.
overlap_clusters Количество ближайших кластеров последнего уровня, в которые добавляется каждый вектор. Если параметр задан, допустимо целое число от 2 до 2048, но не больше значения clusters. Если не задан, сохраняется текущее значение; при отсутствии значения в существующем индексе используется 1.
overlap_ratio Неотрицательный порог отношения расстояний, ограничивающий добавление вектора в дополнительные кластеры; значение 0 отключает порог.
adaptive_clusters Автоматический выбор количества кластеров для каждого значения фильтруемой колонки в индексе с фильтрацией. Принимает true или false.
parallel Максимальное число обработчиков партиций, участвующих в перестроении. Ограничения и значение по умолчанию совпадают с ADD INDEX.

Параметры кластеризации, не указанные в WITH, сохраняют текущие значения. В частности, если не указать clusters и levels, новые значения для текущего размера таблицы не будут подобраны автоматически. При перестроении действуют те же ограничения параметров векторного индекса, что и при создании.

Индекс сохраняет набор индексируемых и покрываемых колонок. Функция расстояния или сходства, тип элементов вектора и размерность вектора наследуются от существующего индекса. Не указывайте distance, similarity, vector_type или vector_dimension в WITH: команда отклоняет эти параметры, даже если их значения совпадают с текущими. Для их изменения создайте отдельный индекс.

Существующий индекс остаётся доступным для запросов и продолжает получать обновления таблицы, пока строится новая версия. После успешного построения YDB атомарно переключается на новую версию. Запросы продолжают использовать прежнее имя индекса. Если перестроение завершится ошибкой или будет отменено до замены, старый индекс останется доступным. Перестроение может продолжиться после перезапуска таблетки управления схемой.

Замена индекса может сделать кешированные планы запросов неактуальными. Во время переключения запрос к индексу может получить временный статус ABORTED. Если это происходит при завершении операции перестроения, повторите запрос целиком с помощью стандартного механизма повторных попыток SDK.

Важно

Новая версия строится по снимку данных и наследует ограничение консистентности при построении векторных индексов. Обновления таблицы во время перестроения могут не попасть в новый индекс. Если требуется полная консистентность, приостановите запись из приложений и дождитесь успешного завершения перестроения. Это временное ограничение планируется устранить в одной из следующих версий YDB.

Удаление индекса

DROP INDEX — удаляет индекс с указанным именем. Приведенный ниже код удалит индекс с именем title_index.

ALTER TABLE `series` DROP INDEX `title_index`;

Также удалить индекс можно с помощью команды table index YDB CLI.

Переименование вторичного индекса

RENAME INDEX — переименовывает индекс с указанным именем. Если индекс с новым именем существует, будет возвращена ошибка.

Возможность атомарной замены индекса под нагрузкой поддерживается командой ydb table index rename YDB CLI и специализированными методами YDB SDK.

Это относится к глобальным вторичным индексам (скрытая индексная таблица и режим --replace). Локальные блум-индексы к такой атомарной замене под нагрузкой не применимы.

Пример переименования индекса:

ALTER TABLE `series` RENAME INDEX `title_index` TO `title_index_new`;
Предыдущая
Следующая