Files
homework/dmedvedev/clickhouse/6.CH_indexes_partitions.sql
T

111 lines
4.5 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Задачи на отработку:
### **Задача 1.**
Таблица `sales`
| id | region | sale_date | amount |
| --- | --- | --- | --- |
| 1 | RU | 2024-05-01 | 100.0 |
| 2 | RU | 2024-05-15 | 120.0 |
| 3 | US | 2024-06-01 | 90.0 |
| 4 | US | 2024-07-03 | 150.0 |
| 5 | DE | 2024-07-04 | 160.0 |
1. Создай таблицу с `PARTITION BY toYYYYMM(sale_date)`.
CREATE TABLE IF NOT EXISTS sales (
id UInt8,
region String,
sale_sate DateTime64,
amount Float64
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(sale_date)
ORDER BY (sale_date, region);
2. Выполни `ALTER TABLE ... DROP PARTITION '202405'`.
УДАЛИЛАСЬ ПАРТИЦИЯ
3. Что произойдет, если не указывать `PARTITION BY`?
ЕСЛИ МЫ ГОВОРИМ ПРО ПРОЦЕСС СОЗДАНИЯ, ТО В ТАКОМ СЛУЧАЕ ВСЕ ДАННЫЕ БУДУТ НАХОДИТЬСЯ ПО УМОЛЧАНИЮ В ОДНОЙ ПАРТИЦИИ.
### **Задача 2.**
Есть таблица `events`, и ты хочешь логически хранить данные **по типу события**.
| id | event_type | event_date |
| --- | --- | --- |
| 1 | login | 2024-06-01 |
| 2 | click | 2024-06-01 |
| 3 | click | 2024-06-02 |
| 4 | purchase | 2024-06-03 |
| 5 | login | 2024-06-04 |
1. Создай таблицу с `PARTITION BY event_type`.
CREATE TABLE IF NOT EXISTS sales (
id UInt8,
event_type String,
event_date Date
)
ENGINE = MergeTree()
PARTITION BY event_type
ORDER BY (event_type, event_date);
2. Удали все события `click` (подсказка: это `ALTER TABLE DROP PARTITION 'click'`).
3. Чем такой подход может быть опасен (подумай про кардинальность значений)?
СЕЙЧАС СОБЫТИЙ ПО ФАКТУ 3, ЭТО МАЛО И УДАЛЕНИЕ БУДЕТ ПРОИСХОДИТЬ БЫСТРО, А ЕСЛИ ПАРТИЦИЙ БУДЕТ 1000, ТО В ТАКОМ СЛУЧАЕ СИСТЕМА БУДЕТ ТОРМОЗИТЬ.
### **Задача 3.**
Ты хочешь разбить таблицу `logs` на 100 партиций по `user_id`, чтобы равномерно распределить объём данных.
| id | user_id | log_time |
| --- | --- | --- |
| 1 | 123 | 2024-07-17 10:00:00 |
| 2 | 456 | 2024-07-17 10:01:00 |
| 3 | 789 | 2024-07-17 10:02:00 |
1. Создай таблицу с `PARTITION BY cityHash64(user_id) % 100`.
CREATE TABLE IF NOT EXISTS logs (
id UInt32,
user_id UInt32,
log_time DateTime64
)
ENGINE = MergeTree()
PARTITION BY cityHash64(user_id) % 100
ORDER BY (user_id, log_time);
2. Что ты выиграешь с точки зрения баланса?
Я СБАЛАНСИРОВАННО РАЗДЕЛЮ ВСЕ ЛОГИ ПО ПАРТИЦИЯМ ПО УНИКАЛЬНОМУ ЮЗЕР АЙДИ
3. Почему такой тип `PARTITION` не ускорит `SELECT * WHERE user_id = 456`?
ПОТОМУ ЧТО В ТАКОМ СЛУЧАЕ ПРИДЕТСЯ ВСЕ РАВНО СКАНИРОВАТЬ ВСЕ ПАРТИЦИИ, ТО ЕСТЬ ВСЮ БАЗУ ДАННЫХ, ВВИДУ ТОГО, ЧТО АЙДИШНИК 456 КЛИКХАУЦС НЕ СМОЖЕТ ПОДСТАВИТЬ В
cityHash64(user_id) ДЛЯ РАСЧЕТА В ХЭЩ ФУНКЦИИ. ПОЭТОМУ ОПТИМИЗАТОРУ НЕОБХОДИМО БУДЕТ ЗАГЛЯНУТЬ В 100 ФАЙЛОВ НА ДИСКЕ .
### **Задача 4.**
В таблице `visits` данные зависят от региона и времени.
| id | region | visit_date |
| --- | --- | --- |
| 1 | RU | 2024-06-01 |
| 2 | RU | 2024-06-15 |
| 3 | US | 2024-06-03 |
| 4 | US | 2024-07-01 |
| 5 | RU | 2024-07-05 |
1. Создай таблицу с `PARTITION BY (region, toYYYYMM(visit_date))`.
CREATE TABLE IF NOT EXISTS visits (
id UInt8,
region String,
visit_date Date
)
ENGINE = MergeTree()
PARTITION BY (region, toYYYYMM(visit_date))
ORDER BY (visit_date, id);
2. Как будет выглядеть имя партиции?
"RU-202406"
"US-202406"
"US-202407"
"RU-202407"
3. Сможешь ли ты эффективно удалить **все июльские данные по `RU`**?
НЕТ КОНЕЧНО, ТАК КАК ЭТИ ДАННЫЕ НАХОДЯТСЯ В ДВУХ ПАРТИЦИЯХ, ТО НЕОБХОДИМО БУДЕТ С ПОМОЩЬЮ УДАЛЯТЬ ЧЕРЕЗ "RU-202407".