Что такое разреженный (sparse) индекс в ClickHouse и как он работает?

Ответ

Разреженный (sparse) индекс в ClickHouse — это основной механизм индексации, который работает не с каждой отдельной строкой, а с большими блоками данных, называемыми гранулами. Его главная задача — быстро отсекать большие объемы данных, которые точно не содержат искомых значений, минимизируя количество чтений с диска.

Как это работает:


  1. Разбиение на гранулы: Все данные в таблице MergeTree физически упорядочены по первичному ключу (ORDER BY). Эти отсортированные данные делятся на гранулы. По умолчанию одна гранула содержит 8192 строки.



  2. Создание "засечек": Для первой строки каждой гранулы ClickHouse создает запись в файле индекса (primary.idx). Эта запись (или "засечка") содержит значения столбцов первичного ключа для этой строки.


  3. Пропуск данных при запросе: Когда выполняется запрос с условием 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, и пропустит все гранулы, относящиеся к другим пользователям. Затем внутри найденных гранул он будет искать нужные даты.

Ключевое преимущество: Такой подход позволяет хранить индекс, который в сотни раз меньше самих данных, и при этом эффективно работать с огромными таблицами, быстро фильтруя данные по диапазонам.