TGViewer
EvApps EvApps @evapps_team · 198 subscribers
Post #1488 160
Всем привет!
Сегодня углубимся в детали ключей, партиций и дополнительных индексов — всё, что нужно для максимальной производительности.

Order Key vs Primary Key
Ранее я упоминал: если не указать PRIMARY KEY явно, ClickHouse использует ключи сортировки (ORDER BY) как первичные ключи.
Но вы можете задать PRIMARY KEY отдельно — он должен быть подмножеством ORDER BY.
CREATE TABLE ecommerce_events
(
    `customer_id` UInt32,
    `action_type` String,
    `event_date` Date,
    `product_id` UInt32,
    `session_token` String
)
ENGINE = MergeTree
PRIMARY KEY (event_date, customer_id)  -- Для индекса
ORDER BY (event_date, customer_id, action_type, product_id);  -- Для сортировки

Что здесь происходит:
— event_date и customer_id — используются и для индекса, и для сортировки
— action_type и product_id — только для сортировки (помогают в ORDER BY запросах)
— session_token — вообще не участвует в сортировке
Зачем это нужно? 
Если вы часто используете ORDER BY в запросах, включение этих столбцов в ORDER BY таблицы ускоряет выполнение — ClickHouse не будет тратить время на дополнительную сортировку.

Partition Key — разбиваем данные
Партиционирование в ClickHouse — это логическое разделение данных на части. По умолчанию все данные в одной партиции, но вы можете изменить это:
CREATE TABLE server_logs_partitioned
(
`server_id` UInt16,
`log_message` String,
`log_timestamp` DateTime
)
ENGINE = MergeTree
PARTITION BY toDate(log_timestamp)
ORDER BY (log_timestamp, server_id);

Что даёт партиционирование:
— Быстрое удаление старых данных — можно удалить целую партицию
— Оптимизация запросов — ClickHouse читает только нужные партиции
— Управление данными — перемещение, копирование партиций
Важно: 
Партиционирование — не для ускорения запросов!

Skip Index — когда ORDER BY не помогает:
Что делать, если нужно искать по столбцу, которого нет в ORDER BY? Например, найти все логи с определённым типом ошибки:
-- Добавляем ngram bloom filter для поиска подстрок
ALTER TABLE server_logs
ADD INDEX error_idx log_message
TYPE ngrambf_v1(3, 256, 2, 0) GRANULARITY 2;

-- Применяем индекс к существующим данным
ALTER TABLE server_logs
MATERIALIZE INDEX error_idx;

Типы Skip Index:
— bloom_filter — для точного совпадения строк
— minmax — для диапазонов (даты, числа)
— ngrambf_v1 — для поиска подстрок
— tokenbf_v1 — для поиска отдельных слов

Case Study: оптимизация метрик IoT-устройств

Допустим, у нас есть данные с 50K IoT-устройств. Мы хотим:
1. Быстро искать метрики по времени и device_id
2. Фильтровать по типу сенсора
3. Искать по статусу ошибки
CREATE TABLE iot_metrics
(
`device_id` UInt32,
`sensor_type` String,
`metric_time` DateTime,
`value` Float32,
`error_flag` UInt8
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(metric_time) -- Для архивации старых данных
PRIMARY KEY (metric_time, device_id) -- Основные фильтры
ORDER BY (metric_time, device_id, sensor_type) -- Сортировка + фильтры
SETTINGS index_granularity = 8192;

-- Добавляем skip index для поиска ошибок
ALTER TABLE iot_metrics
ADD INDEX error_sk error_flag TYPE minmax GRANULARITY 1;

Результат:
— По времени+устройству — мгновенно (первичный ключ)
— По типу сенсора — быстро (часть ORDER BY)
— По ошибкам — эффективно (skip index)
— Архивация данных — DROP PARTITION для старых месяцев

Главные правила проектирования:
1.ORDER BY — сначала столбцы для самых частых фильтров
2.PRIMARY KEY — подмножество ORDER BY (обычно первые 2-3 столбца)
3.PARTITION BY — только для управления данными, не для скорости
4.Skip Index — для столбцов вне ORDER BY, но с фильтрами

Что дальше?
В следующем посте мы проведём детальное сравнение производительности ClickHouse и MySQL на практических примерах

#ClickHouse #БазыДанных #Производительность #Индексы #Партиционирование #Оптимизация #MySQL
  • 👍 3
More from @evapps_team
  1. Sep 21, 2026🧩 Что тут не так? Код-загадка Формат новый - показываю код, ты угадываешь подвох, ниже ра…
  2. Sep 18, 2026🎭 Мифы про производительность, в которые верят даже опытные Миф 1: "Меньше строк кода - б…
  3. Sep 16, 2026🚨 Как перевод денег уронил нам прод ⏰ 19:10 Задеплоили долгожданное - переводы между коше…
  4. Sep 14, 2026🗃 Кэш поставили, а он отдаёт старьё В программировании две сложные вещи - инвалидация кэш…
  5. Sep 11, 2026🔌 "Too many connections" - и почему база падает под нагрузкой Под нагрузкой прилетает FAT…
  6. Sep 11, 2026Пока вы наслаждаетесь пятницей, мы напоминаем, что уже завтра стартует одна из наших любим…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →