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-go лучшие практики
16.04.2024