Статья

Индексы и способы ускорения запросов в Data Lakehouse

Технологии
Оптимизация запросов в Селене — это комплексная задача, требующая понимания как структуры данных и их физического представления в хранилище, так и характера рабочих нагрузок. Один из ключевых способов ускорения аналитических запросов ― корректное использование индексов. Индексация позволяет резко сократить объем данных, которые нужно прочитать при выполнении фильтрации или соединений, что особенно важно в работе с большими объемами данных.
Грамотный выбор типов индексов, анализ планов выполнения запросов и регулярный мониторинг помогают добиться значительного повышения производительности. При этом важно помнить: универсального решения нет, а оптимальная стратегия всегда зависит от модели данных и паттернов использования.

Основы индексации в Селене

В основе Селены лежит технология StarRocks, которая использует несколько типов индексов для оптимизации производительности запросов. Основной механизм индексации базируется на колоночном хранении и архитектуре с сегментным разделением (segment-based architecture), что позволяет эффективно сжимать данные и ускорять операции чтения.
Типы индексов:
  • Primary Key Index - основной индекс, обеспечивающий уникальность записей и быстрый доступ к данным
  • Bloom Filter Index - фильтрующий индекс для ускорения проверки наличия значений
  • Индекс битовой карты (Bitmap index) подходит для запросов по столбцам с высокой кардинальностью или комбинациям нескольких столбцов с низкой кардинальностью.
  • Min/Max Index - индекс для хранения минимальных и максимальных значений в сегментах
  • Zone Map Index - индекс для оптимизации фильтрации по диапазонам

Индекс битовой карты

Битовый индекс демонстрирует практически идеальную производительность фильтрации, позволяя отсеивать до 999 строк из каждой тысячи обрабатываемых.
Bitmap-индексы наиболее эффективны в следующих случаях:
  • При работе со столбцами высокой кардинальности (10 – 100 тыс. уникальных значений)
  • При комбинации нескольких столбцов с низкой кардинальностью
Оптимальные сценарии использования:
  • Запросы с условиями =, IN, NOT IN
  • Комбинации нескольких условий фильтрации
  • Аналитические запросы с высокой селективностью
Примеры применения:
  • Фильтрация по дате и региону: WHERE date = '2025-11-12' AND region IN ('Москва', 'СПб')
  • Сегментация по нескольким атрибутам: WHERE gender = 'male' AND age_group = '25-35'
  • Фильтрация по сложным комбинациям: WHERE status = 'active' AND category = 'premium'
Не рекомендуется использовать bitmap-индексы:
  • Для столбцов с кардинальностью менее 10 тыс.
  • При работе с типами FLOAT, DOUBLE, BOOLEAN, DECIMAL

Индекс Блюма

Индекс Блума подходит для столбцов с достаточно высокой кардинальностью. Это могут быть столбцы идентификаторов.
Индекс Блума n-грамм — это особый тип индекса фильтра Блума, обычно используемый для ускорения запросов LIKE или операций функций ngram_search и ngram_search_case_insensitive.
Индекс Блюма рекомендуется использовать для:
  • Фильтрации больших наборов данных по столбцам с уникальными значениями или с большим количеством уникальных значений
  • Предварительной фильтрации перед сложными запросами
  • Оптимизации операций соединения таблиц
  • Ускорения поиска по множеству значений в операторе IN

ZoneMap индекс

ZoneMap Index эффективен в следующих случаях:
  • При работе с большими объемами данных, где требуется быстрая оценка статистических характеристик сегментов
  • В сценариях с фильтрацией по диапазонам значений (range queries)
  • При выполнении запросов, где важна быстрая оценка возможности исключения целых сегментов данных из обработки
Преимущества индекса ZoneMap
  • Минимальные накладные расходы на поддержание индекса
  • Автоматическая генерация системой
  • Эффективная работа с запросами на основе статистических характеристик
Рекомендации по использованию:
  • Используйте ZoneMap Index совместно с другими типами индексов для максимальной эффективности
  • Учитывайте, что ZoneMap Index хранит статистику по минимальным, максимальным значениям и наличию NULL
  • Проводите тестирование производительности перед внедрением
  • Оценивайте соотношение затрат на хранение индекса и выгоды от ускорения запросов
Оптимальные сценарии применения:
  • Аналитические запросы с фильтрацией по диапазонам
  • Исторические данные с временными метками
  • Геоданные с координатами или другими числовыми значениями
  • Финансовые данные с числовыми показателями
  • Логи и события с временными отметками
Примеры запросов, где применение индекса ZoneMap даст эффект:
Фильтрация по диапазону дат:
sql
SELECT * FROM sales
WHERE sale_date BETWEEN '2025-01-01' AND '2025-12-31'
AND amount > 1000;
Анализ временных периодов:
sql
SELECT COUNT(*)
FROM transactions
WHERE transaction_time >= '2025-11-01 00:00:00'
AND transaction_time < '2025-11-02 00:00:00';
Фильтрация числовых значений:
sql
SELECT product_id
FROM inventory
WHERE quantity BETWEEN 10 AND 100
AND price < 5000;
Анализ географических данных:
SELECT location_id
FROM geo_data
WHERE latitude BETWEEN 55.0 AND 56.0
AND longitude BETWEEN 37.0 AND 38.0;
Фильтрация по финансовым показателям:
SELECT account_id
FROM financials
WHERE balance > 0
AND last_transaction > '2025-01-01';
Оптимизация агрегатных запросов:
SELECT AVG(temperature)
FROM weather_data
WHERE temperature > 25
AND date >= '2025-06-01';
Фильтрация по статусам:
SELECT user_id
FROM user_activity
WHERE status IN ('active', 'pending')
AND last_login > '2025-10-01';
Сравнение с другими индексами:
Когда ZoneMap лучше Bitmap:
-- ZoneMap эффективен для:
SELECT * FROM logs
WHERE timestamp > '2025-01-01'
AND duration > 1000; -- диапазонный запрос
-- Bitmap менее эффективен:
SELECT * FROM users
WHERE gender = 'male'
AND age = 30; -- низкая кардинальность
Когда ZoneMap лучше Bloom:
-- ZoneMap оптимален для:
SELECT * FROM orders
WHERE order_date BETWEEN '2025-01-01' AND '2025-12-31'
AND total_amount > 10000;
-- Bloom менее эффективен:
SELECT * FROM customers
WHERE id IN (1001, 1002, 1003); -- точный поиск ID

Префиксные индексы

Префиксный индекс — это автоматически создаваемый индекс, который формируется при записи данных в таблицу. Он создается на основе первичных ключей и оптимизирует запросы, использующие начальные столбцы ключа.
Принцип работы
  • Создается на основе первых столбцов первичного ключа
  • Работает на уровне сегментов данных
  • Оптимизирует фильтрацию по начальным столбцам
  • Автоматически поддерживается системой
Префиксные индексы лучше использовать:
  • В запросах с точными совпадениями по начальным столбцам
  • При фильтрации по первым столбцам первичного ключа
  • В операциях с диапазонами значений
  • При сортировке по ключевым полям
Не рекомендуется применять:
  • Для столбцов с типом VARCHAR в начале ключа
  • Для типов FLOAT и DOUBLE
  • Когда часто меняются данные в начальных столбцах
  • При работе с короткими ключами (менее 3 столбцов)
Практические рекомендации по использованию префиксного индекса:
  • Размещайте часто используемые поля фильтрации в начале первичного ключа
  • Ограничьте длину префикса до 3-5 столбцов
  • Используйте целочисленные типы для ключевых столбцов
  • Следите за размером префикса (не более 36 байт)
Примеры эффективного использования
-- Хороший пример
CREATE TABLE sales (
region_id INT,
city_id INT,
store_id INT,
sale_date DATE,
amount DECIMAL(18,2)
) PRIMARY KEY (region_id, city_id, store_id, sale_date);
-- Эффективный запрос
SELECT * FROM sales
WHERE region_id = 1 AND city_id = 10;
Примеры неэффективного использования
-- Плохой пример
CREATE TABLE users (
username VARCHAR(50),
user_id INT,
registration_date DATE
) PRIMARY KEY (username, user_id);
-- Неэффективный запрос
SELECT * FROM users
WHERE username LIKE 'john%';
Сравнение с другими индексами
Преимущества префиксных индексов:
  • Автоматическая генерация
  • Эффективная фильтрация по начальным столбцам
  • Оптимизация сортировки
  • Низкие накладные расходы
Недостатки:
  • Ограничения по типам данных
  • Размер префикса ограничен
  • Неэффективность для сложных условий

Порядковые индексы

Порядковый индекс — это встроенный тип индекса, который автоматически создается системой при формировании страниц данных.
Порядковый индекс создается одновременно с генерацией страницы данных. Каждая страница имеет фиксированный размер 64 КБ. Индекс содержит информацию о начальной строке страницы и позволяет определять физический адрес данных по номеру строки.
Колоночное хранение лежит в основе работы порядковых индексов.
Преимущества использования:
  • Быстрая адресация данных по номеру строки
  • Оптимизация доступа к физическим адресам
  • Автоматическое создание системой
  • Эффективная работа с постраничным доступом
Порядковые индексы особенно эффективны в следующих случаях:
  • Операции с большими объемами данных
  • Запросы, требующие прямого доступа к строкам
  • Постраничный доступ к информации
Важные характеристики:
  • Работают на уровне страниц данных
  • Не требуют дополнительного управления
  • Оптимизируют физические операции чтения
  • Не влияют на логику запросов напрямую
Отличия от префиксных индексов:
  • Префиксные индексы работают с сортировкой данных
  • Порядковые индексы оперируют физическими адресами
  • Разные механизмы оптимизации запросов
Рекомендации по использованию:
  • Учитывать размер страницы при проектировании
  • Использовать в сочетании с другими типами индексов
  • Не пытаться управлять индексами вручную
  • Опираться на автоматическую оптимизацию системы
Примеры эффективности
Порядковые индексы показывают высокую эффективность в следующих запросах:
-- Эффективный доступ по номеру строки
SELECT * FROM table_name WHERE row_number = 1000;
-- Постраничный доступ
SELECT column_name FROM table_name LIMIT 1000 OFFSET 5000;
-- Операции сдиапазоном строк
SELECT * FROM table_name WHERE row_number BETWEEN 100 AND 200;

Методы оптимизации запросов

Ключевую роль в производительности играет секционирование данных:
  • Горизонтальное партиционирование по диапазонам
  • Секционирование по списку значений
  • Временное секционирование
Также влияют на скорость выполнения запросов стратегии хранения:
  • Replicated Storage - репликация данных для отказоустойчивости
  • Erasure Coding - кодирование для экономии места
  • Bucketed Storage - распределение данных по бакетам
Практические рекомендации по оптимизации
  • Предварительный анализ запросов помогает определить оптимальные стратегии индексации
  • Профилирование нагрузки позволяет выявить узкие места
  • Настройка параметров хранения влияет на производительность: размер сегментов, уровень сжатия, стратегия репликации
Для ускорения сложных запросов Селена применяет следующие механизмы:
·Materialized Views значительно ускоряют выполнение повторяющихся запросов: предварительные вычисления, кэширование результатов, оптимизация часто используемых агрегатов
·Query Rewrite позволяет оптимизировать запросы автоматически для переупорядочивания операций, удаления избыточных вычислений и для оптимизации соединений

Мониторинг и настройка

Производительность системы требует постоянного мониторинга, в том числе:
  • Анализа планов выполнения
  • Отслеживания использования ресурсов
  • Оценки эффективности индексов
Настройка параметров включает конфигурацию памяти, оптимизацию параллелизма управление буфером запросов.

Рекомендации по внедрению оптимизации

  • Добавляйте индексы постепенно, проверяя эффект на тестовых наборах
  • Перепроверяйте производительность после изменений
  • Выделяйте индексацию и стратегию хранения для ключевых таблиц
  • Масштабируйте ресурсы под фактическую нагрузку