Ответ
Разреженный (sparse) индекс в ClickHouse — это основной механизм индексации, который работает не с каждой отдельной строкой, а с большими блоками данных, называемыми гранулами. Его главная задача — быстро отсекать большие объемы данных, которые точно не содержат искомых значений, минимизируя количество чтений с диска.
Как это работает:
Разбиение на гранулы: Все данные в таблице
MergeTree
физически упорядочены по первичному ключу (ORDER BY
). Эти отсортированные данные делятся на гранулы. По умолчанию одна гранула содержит 8192 строки.Создание "засечек": Для первой строки каждой гранулы ClickHouse создает запись в файле индекса (
primary.idx
). Эта запись (или "засечка") содержит значения столбцов первичного ключа для этой строки.Пропуск данных при запросе: Когда выполняется запрос с условием
WHERE
по первичному ключу (например,WHERE EventDate = '2023-10-26'
), ClickHouse не сканирует все данные, а:- Смотрит на "засечки" в файле индекса.
- Определяет, в каких диапазонах (гранулах) могут находиться искомые данные.
- Читает с диска только эти гранулы, пропуская остальные.
Пример:
-- Таблица отсортирована по UserID и EventDate
CREATE TABLE user_actions (
UserID UInt32,
EventDate Date,
Action String
) ENGINE = MergeTree()
ORDER BY (UserID, EventDate);
При запросе WHERE UserID = 123 AND EventDate > '2023-01-01'
ClickHouse будет использовать индекс, чтобы найти гранулы, где UserID
равен 123
, и пропустит все гранулы, относящиеся к другим пользователям. Затем внутри найденных гранул он будет искать нужные даты.
Ключевое преимущество: Такой подход позволяет хранить индекс, который в сотни раз меньше самих данных, и при этом эффективно работать с огромными таблицами, быстро фильтруя данные по диапазонам.