E
EvApps
@evapps_team198 подп.
151просмотров
76.3%от подписчиков
30 декабря 2025 г.
Score: 166
Всем привет! Сегодня углубимся в детали ключей, партиций и дополнительных индексов — всё, что нужно для максимальной производительности. 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
151
просмотров
3981
символов
Нет
эмодзи
Нет
медиа

Другие посты @evapps_team

Все посты канала →
Всем привет! Сегодня углубимся в детали ключей, партиций и д — @evapps_team | PostSniper