Под капотом
Фишки ClickHouse
В этой главе вы узнаете об основных фишках ClickHouse, которые имеют прямое отношение к оптимизации запросов.
Разреженный индекс
В строковых СУБД индексу соответствует одна строка, т.е. индекс содержит одну запись на каждую строку.
ClickHouse создан для работы с таблицами на миллионы и миллиарды строк и хранить индекс для каждой строки это очень дорого (по памяти). Поэтому в ClickHouse вместо индексации каждой строки, индекс содержит одну запись ('mark') на группу строк — гранулу. Такая техника называется разреженный индекс.
Размер гранулы полностью помещается в оперативной памяти. И вместо поиска одной строки, индекс ищет гранулу целиком. И уже после этого в ней ищется нужная строка, что гораздо быстрее т.к. вся гранула выгружается в оперативную память.
Размер гранулы определяется настройкой index_granularity при создании таблицы и по умолчанию она равна 8192 строки.
Чем ниже гранулярность индекса, тем больше памяти таблица занимает на жестком диске. Например, если взять таблицу с гранулярностью 8192 и размером 450 кб, и создать такую же таблицу, но с гранулярностью 1, она станет весить больше 9 мб (т.е. примерно в 20 раз больше).
Поэтому для небольших таблиц как правило уменьшают гранулярность, чтобы ускорить поиск, а для для больших оставляют настройку по умолчанию для экономии места на диске.
Подробнее об индексации в ClickHouse можно почитать в документации
Встроенный оптимизитор
В ClickHouse используется внутренняя оптимизация запросов. Мы пишем запрос, дальше его обрабатывает оптимизатор, и уже потом производит операции с диском, выполняя оптимизированный запрос. Поэтому написанный пользователем запрос может отличаться от выполненного системой. Запрос, который будет выполняться можно увидеть при помощи оператора EXPLAIN.
Порядок выполнения запросов
Один из способов оптимизации это влияние на порядок выполнения. Сервер ClickHouse выполняет запрос в следующем порядке:
FROM
PREWHERE (специфический внутренний оператор ClickHouse)
JOIN
WHERE
GROUP BY
HAVING
SELECT
DISTINCT
ORDER BY
LIMIT
PREWHERE — это специальный оператор, который отвечает за выполнение фильтрации до выполнения JOIN или GROUP BY. Даже если запрос составлен неоптимально, всё равно CH попробует выполнить фильтрацию до соединения или группировки. Примеры такой оптимизации можно увидеть в главах JOIN и HAVING.
Кэширование
ClickHouse кэширует данные, сохраняя некоторые SELECT запросы и проводя дальнейшие операции уже из кэша. Доступ из кэша гораздо быстрее, чем чтение с жёсткого диска, засчёт этого мы получаем прирост в скорости. Подробнее об этом можно почитать в документации.
Last updated