ClickHouse: если поле уже есть в ORDER BY, имеет ли смысл создавать еще и пропускающий индекс по этому полю?
Если поле уже включено в ORDER BY при создании таблицы в ClickHouse, то обычно не имеет смысла создавать отдельный пропускающий индекс (skip index) по этому полю.
Вот почему:
Как работает ORDER BY в ClickHouse:
- Когда вы указываете поля в
ORDER BYпри создании таблицы, ClickHouse использует эти поля для сортировки данных внутри таблицы. - Это создаёт составной индекс, который оптимизирует выборку данных, фильтруя и сортируя их в соответствии с полями в
ORDER BY. - Такой индекс уже выполняет роль индексации для фильтрации и поиска данных по этим полям.
Пропускающие индексы (skip indexes):
- Пропускающий индекс в ClickHouse используется для того, чтобы пропускать блоки данных, которые явно не соответствуют запросу. Например, если запрос фильтрует по полю
created_at, и вы добавляете пропускающий индекс на это поле, то ClickHouse будет проверять только те блоки данных, которые могут соответствовать запросу. - Пропускающие индексы полезны для ускорения выборок по полям, которые не входят в
ORDER BY, или когда запросы выполняются по диапазонам значений, а не по точным совпадениям.
Почему не стоит создавать пропускающий индекс на поле, уже включённое в ORDER BY:
- Избыточность: Если поле уже включено в
ORDER BY, то оно уже индексируется через механизм сортировки данных внутри таблицы. Создание дополнительного пропускающего индекса для этого поля будет избыточным и не даст значительного выигрыша по производительности. - Перегрузка: Пропускающие индексы занимают дополнительное пространство на диске. Если поле уже индексируется через
ORDER BY, дополнительный индекс увеличит потребление памяти и может даже ухудшить производительность при записи данных (индекс нужно будет поддерживать в актуальном состоянии). - Эффективность: Если запросы используют сортировку или фильтрацию по полям, указанным в
ORDER BY, то уже существующий составной индекс будет использоваться эффективно. В большинстве случаев, отдельный пропускающий индекс не добавит существенного улучшения.
Пример
Предположим, у вас есть таблица с таким ORDER BY:
|
1 2 3 4 5 6 7 8 9 |
CREATE TABLE example_table ( id UInt64, name String, created_at DateTime, amount Float32 ) ENGINE = MergeTree() ORDER BY (created_at, id); |
В этом случае, created_at и id уже участвуют в составном индексе по умолчанию через ORDER BY.
Создание пропускающего индекса для поля created_at в этом случае будет лишним:
|
1 2 3 4 5 6 7 8 9 10 |
CREATE TABLE example_table ( id UInt64, name String, created_at DateTime, amount Float32, INDEX idx_created_at (created_at) TYPE minmax GRANULARITY 1 -- Это избыточно! ) ENGINE = MergeTree() ORDER BY (created_at, id); |
Здесь created_at уже эффективно индексируется через ORDER BY, и создание отдельного пропускающего индекса только увеличит нагрузку на систему без явных преимуществ.
Исключения, когда это может быть полезно:
- Фильтрация по полям, не входящим в
ORDER BY: Если у вас есть дополнительные поля, по которым часто выполняются фильтрации, но которые не входят вORDER BY, то создание пропускающих индексов на этих полях может быть полезным. - Диапазонные запросы: Если вы часто выполняете запросы с диапазонными фильтрами (например, по времени), пропускающие индексы на этих полях могут ускорить выполнение запросов, даже если эти поля не указаны в
ORDER BY.
Итог
Если поле уже включено в ORDER BY, то не имеет смысла создавать дополнительный пропускающий индекс для этого поля, так как это приведет к избыточной индексации и дополнительной нагрузке на систему. Вместо этого стоит использовать составной индекс, который уже автоматически создается через ORDER BY.
Recommended Posts
ClickHouse в вопросах и ответах
28.04.2024
