Перейти к содержимому
Последнее обновление

Индекс NGram BloomFilter

Индекс NGram BloomFilter представляет собой Skip Index, специально разработанный для ускорения запросов нечеткого поиска LIKE '%pattern%' по строковым столбцам. Он построен на основе индекса BloomFilter и использует токенизацию N-Gram: перед записью в BloomFilter текст разбивается на группы из соседних символов. Это обеспечивает быструю фильтрацию при нечетком поиске.

Основное преимущество: В подходящих сценариях индекс NGram BloomFilter может ускорить запросы от нескольких раз до десяти по сравнению с полным сканированием без индекса (см. пример ускорения в 8 раз в разделе Пример использования).

Принцип работы индекса​

Ngram Bloomfilter

Токенизация N-Gram разбивает предложение или фрагмент текста на группы из соседних символов. Например, токенизация строки 'This is a simple ngram example' при N = 3 дает следующие 4 группы слов:

  • 'This is a'
  • 'is a simple'
  • 'a simple ngram'
  • 'simple ngram example'

Основные различия между индексом NGram BloomFilter и обычным индексом BloomFilter:

Критерий сравненияИндекс BloomFilterИндекс NGram BloomFilter
Записываемое содержимоеИсходные значения столбцаКаждая группа, полученная при токенизации исходного текста методом N-Gram
Ускоряемые типы запросовЗапросы на равенство (=, IN)Запросы нечеткого поиска LIKE '%pattern%'
Поддерживаемые типы столбцовРазличные типы данныхТолько строковые столбцы

Процесс ускорения запроса:

  1. К pattern в выражении LIKE '%pattern%' применяется токенизация N-Gram.
  2. Для каждой полученной группы последовательно проверяется ее наличие в BloomFilter.
  3. Если группа отсутствует в BloomFilter, соответствующий блок данных не может удовлетворять условию LIKE и его можно пропустить.
  4. Пропуск блоков данных, не соответствующих условию, сокращает IO и ускоряет запрос.

Сценарии использования​

Индекс NGram BloomFilter подходит для следующих сценариев:

  • Ускорение запросов нечеткого поиска LIKE '%pattern%' по строковым столбцам.
  • Число последовательных символов в шаблоне LIKE больше либо равно значению gram_size, заданному для индекса.
Ограничения использования
  • Поддерживаются только строковые столбцы, а ускорение доступно только для запросов LIKE.
  • Индекс NGram BloomFilter и обычный индекс BloomFilter взаимоисключающие. Для одного столбца можно выбрать только один из них.
  • Эффективность индекса анализируется так же, как и для индекса BloomFilter.

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

Создание индекса​

Создание индекса при создании таблицы​

Добавьте определение индекса после определения COLUMN в операторе создания таблицы:

INDEX `idx_column_name` (`column_name`) USING NGRAM_BF
PROPERTIES("gram_size"="3", "bf_size"="1024")
COMMENT 'username ngram_bf index'

Описание синтаксиса​

ПараметрОбязательностьОписание
idx_column_name (column_name)Обязательныйcolumn_name — имя столбца, для которого создается индекс; столбец должен быть определен ранее. idx_column_name — имя индекса, которое должно быть уникальным в пределах таблицы
USING NGRAM_BFОбязательныйЗадает тип индекса: NGram BloomFilter
PROPERTIESНеобязательныйЗадает дополнительные свойства индекса NGram BloomFilter. Подробности приведены в таблице ниже
COMMENTНеобязательныйЗадает комментарий к индексу
Рекомендация по именованию

Рекомендуется добавлять к именам индексов префикс idx_, например idx_review_body.

Параметры PROPERTIES​

СвойствоОписание
gram_sizeЗначение N в N-Gram: каждые N последовательных символов образуют группу. Например, строка 'This is a simple ngram example' разбивается на 4 группы слов при N = 3. Рекомендуется задавать минимальную длину строки поиска в запросе LIKE, но не менее 2.
bf_sizeРазмер BloomFilter в битах. Определяет размер индекса для каждого блока данных. Чем больше значение, тем больше требуется места для хранения, но тем ниже вероятность коллизий хешей.

Рекомендуемая конфигурация: Обычно рекомендуется начать с "gram_size"="3" и "bf_size"="1024", а затем скорректировать параметры на основе Query Profile.

Просмотр индексов​

-- Method 1: In the INDEX section of the table schema, USING NGRAM_BF marks an NGram BloomFilter index
SHOW CREATE TABLE table_name;

-- Method 2: An IndexType of NGRAM_BF marks an NGram BloomFilter index
SHOW INDEX FROM table_name;

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

ALTER TABLE table_ngrambf DROP INDEX idx_ngrambf;

Изменение индекса​

Индекс NGram BloomFilter можно добавить в существующую таблицу двумя способами:

-- Method 1: Use CREATE INDEX
CREATE INDEX idx_column_name2(column_name2) ON table_ngrambf
USING NGRAM_BF
PROPERTIES("gram_size"="3", "bf_size"="1024")
COMMENT 'username ngram_bf index';

-- Method 2: Use ALTER TABLE ADD INDEX
ALTER TABLE table_ngrambf
ADD INDEX idx_column_name2(column_name2) USING NGRAM_BF
PROPERTIES("gram_size"="3", "bf_size"="1024")
COMMENT 'username ngram_bf index';

Использование индекса​

Включение проталкивания функций​

Перед использованием индекса NGram BloomFilter включите проталкивание функций (function pushdown; параметр enable_function_pushdown по умолчанию имеет значение false):

SET enable_function_pushdown = true;

Задействование индекса для ускорения​

Индекс NGram BloomFilter автоматически используется для ускорения запросов LIKE, например:

SELECT count() FROM table1 WHERE message LIKE '%error%';

Анализ эффективности индекса​

Эффект ускорения за счет индекса BloomFilter (включая NGram BloomFilter) можно оценить по следующим метрикам в Query Profile:

МетрикаЗначение
RowsBloomFilterFilteredЧисло строк, отфильтрованных индексом BloomFilter. Для оценки эффективности фильтрации можно сравнить его с другими метриками Rows
BlockConditionsFilteredBloomFilterTimeВремя, затраченное на работу индекса BloomFilter

Пример использования​

Ниже на примере набора данных с отзывами пользователей о товарах Amazon amazon_reviews показано, как использовать индекс NGram BloomFilter и какое ускорение он обеспечивает.

Шаг 1: Создание таблицы​

CREATE TABLE `amazon_reviews` (
`review_date` int(11) NULL,
`marketplace` varchar(20) NULL,
`customer_id` bigint(20) NULL,
`review_id` varchar(40) NULL,
`product_id` varchar(10) NULL,
`product_parent` bigint(20) NULL,
`product_title` varchar(500) NULL,
`product_category` varchar(50) NULL,
`star_rating` smallint(6) NULL,
`helpful_votes` int(11) NULL,
`total_votes` int(11) NULL,
`vine` boolean NULL,
`verified_purchase` boolean NULL,
`review_headline` varchar(500) NULL,
`review_body` string NULL
) ENGINE=OLAP
DUPLICATE KEY(`review_date`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`review_date`) BUCKETS 16
PROPERTIES (
"replication_allocation" = "tag.location.default: 1",
"compression" = "ZSTD"
);

Шаг 2: Загрузка данных​

1. Скачайте набор данных

Используйте wget или другой инструмент, чтобы скачать набор данных по следующим URL:

https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2010.snappy.parquet
https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2011.snappy.parquet
https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2012.snappy.parquet
https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2013.snappy.parquet
https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2014.snappy.parquet
https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2015.snappy.parquet

2. Загрузите данные через Stream Load

curl --location-trusted -u root: -T amazon_reviews_2010.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2011.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2012.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2013.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2014.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2015.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
Ограничение размера файла

Размер указанных выше файлов может превышать 10 ГБ. Измените параметр streaming_load_max_mb в be.conf, чтобы не превысить ограничение размера загружаемого файла в Stream Load. Следующая команда применяет изменение динамически (выполните ее на каждом BE):

curl -X POST http://{be_ip}:{be_http_port}/api/update_config?streaming_load_max_mb=32768

3. Проверьте загрузку данных

Выполните SQL-запрос с count(), чтобы убедиться, что данные успешно загружены:

mysql> SELECT COUNT() FROM amazon_reviews;
+-----------+
| count(*) |
+-----------+
| 135589433 |
+-----------+

Шаг 3: Сравнение производительности​

Сценарий 1: Запрос без индекса (время выполнения 7.60 с)

SELECT
product_id,
any_value(product_title),
AVG(star_rating) AS rating,
COUNT() AS count
FROM
amazon_reviews
WHERE
review_body LIKE '%is super awesome%'
GROUP BY
product_id
ORDER BY
count DESC,
rating DESC,
product_id
LIMIT 5;

Результат запроса:

+------------+------------------------------------------+--------------------+-------+
| product_id | any_value(product_title) | rating | count |
+------------+------------------------------------------+--------------------+-------+
| B00992CF6W | Minecraft | 4.8235294117647056 | 17 |
| B009UX2YAC | Subway Surfers | 4.7777777777777777 | 9 |
| B00DJFIMW6 | Minion Rush: Despicable Me Official Game | 4.875 | 8 |
| B0086700CM | Temple Run | 5 | 6 |
| B00KWVZ750 | Angry Birds Epic RPG | 5 | 6 |
+------------+------------------------------------------+--------------------+-------+
5 rows in set (7.60 sec)

Сценарий 2: После добавления индекса NGram BloomFilter (время выполнения 0.93 с)

Добавьте индекс:

ALTER TABLE amazon_reviews
ADD INDEX review_body_ngram_idx(review_body) USING NGRAM_BF
PROPERTIES("gram_size"="10", "bf_size"="10240");

Выполните тот же запрос еще раз:

+------------+------------------------------------------+--------------------+-------+
| product_id | any_value(product_title) | rating | count |
+------------+------------------------------------------+--------------------+-------+
| B00992CF6W | Minecraft | 4.8235294117647056 | 17 |
| B009UX2YAC | Subway Surfers | 4.7777777777777777 | 9 |
| B00DJFIMW6 | Minion Rush: Despicable Me Official Game | 4.875 | 8 |
| B0086700CM | Temple Run | 5 | 6 |
| B00KWVZ750 | Angry Birds Epic RPG | 5 | 6 |
+------------+------------------------------------------+--------------------+-------+
5 rows in set (0.93 sec)

Сравнение производительности:

СценарийВремяПрирост производительности
Без индекса7.60 сБазовый уровень
После добавления индекса NGram BloomFilter0.93 сПримерно в 8 раз

Ограничения индекса для шаблонов LIKE с экранированием​

Начиная с версии 4.1.5, запросы LIKE с пользовательским ESCAPE или обратной косой чертой в шаблоне не используют NGRAM Bloom Filter для отсечения блоков данных, чтобы избежать ошибочной фильтрации. Такие запросы по-прежнему поддерживаются и выполняются с обычным сканированием. Для шаблонов LIKE без экранирования индекс по-прежнему может использоваться при соблюдении существующих условий.