homework, pet project DE Dmitry_Medvedev #1
@@ -0,0 +1,146 @@
|
||||
-- Индексы и сжатие - Партиции --
|
||||
|
||||
-- #1
|
||||
/*
|
||||
1. Создай таблицу sales с `PARTITION BY toYYYYMM(sale_date)`.
|
||||
2. Выполни `ALTER TABLE ... DROP PARTITION '202405'`.
|
||||
3. Что произойдет, если не указывать `PARTITION BY`? <- удалит все данные из таблицы. партиция то одна :)
|
||||
|
||||
*/
|
||||
|
||||
DROP TABLE IF EXISTS dsolovianov.sales ON CLUSTER clickhouse_cluster SYNC;
|
||||
|
||||
CREATE TABLE dsolovianov.sales
|
||||
ON CLUSTER clickhouse_cluster
|
||||
(
|
||||
id UInt64,
|
||||
region String,
|
||||
sale_date Date,
|
||||
amount Float64
|
||||
) ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse/tables/{shard}/dsolovianov/sales',
|
||||
'{replica}'
|
||||
)
|
||||
PARTITION BY toYYYYMM(sale_date)
|
||||
ORDER BY (region, sale_date);
|
||||
|
||||
INSERT INTO dsolovianov.sales (id, region, sale_date, amount) VALUES
|
||||
(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');
|
||||
|
||||
ALTER TABLE dsolovianov.sales DROP PARTITION '202405';
|
||||
|
||||
SELECT *
|
||||
FROM dsolovianov.sales;
|
||||
|
||||
-- #2
|
||||
/*
|
||||
1. Создай таблицу с `PARTITION BY event_type`.
|
||||
2. Удали все события `click` (подсказка: это `ALTER TABLE DROP PARTITION 'click'`).
|
||||
3. Чем такой подход может быть опасен (подумай про кардинальность значений)?
|
||||
При большом количестве уникальных event_type создастся много мелких партиций.
|
||||
*/
|
||||
DROP TABLE IF EXISTS dsolovianov.events ON CLUSTER clickhouse_cluster SYNC;
|
||||
|
||||
CREATE TABLE dsolovianov.events
|
||||
ON CLUSTER clickhouse_cluster
|
||||
(
|
||||
id UInt64,
|
||||
event_type String,
|
||||
event_date Date
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse/tables/{shard}/dsolovianov/events',
|
||||
'{replica}'
|
||||
)
|
||||
PARTITION BY event_type
|
||||
ORDER BY (event_date, id);
|
||||
|
||||
INSERT INTO dsolovianov.events (id, event_type, event_date) VALUES
|
||||
(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');
|
||||
|
||||
ALTER TABLE dsolovianov.events DROP PARTITION 'click';
|
||||
|
||||
-- #3
|
||||
/*
|
||||
1. Создай таблицу с `PARTITION BY cityHash64(user_id) % 100`.
|
||||
2. Что ты выиграешь с точки зрения баланса?
|
||||
Данные распределятся примерно поровну между 100 партициями. Упрощается управление удалением старых данных (можно дропать целые партиции)
|
||||
3. Почему такой тип `PARTITION` не ускорит `SELECT * WHERE user_id = 456`?
|
||||
Потому что партиции определяются хэшем, а не прямым значением user_id и к тому же сортировка в партициях по log_time, а не user_id.
|
||||
|
||||
*/
|
||||
|
||||
DROP TABLE IF EXISTS dsolovianov.logs ON CLUSTER clickhouse_cluster SYNC;
|
||||
|
||||
CREATE TABLE dsolovianov.logs
|
||||
ON CLUSTER clickhouse_cluster
|
||||
(
|
||||
id UInt64,
|
||||
user_id UInt64,
|
||||
log_time DateTime
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse/tables/{shard}/dsolovianov/logs',
|
||||
'{replica}'
|
||||
)
|
||||
PARTITION BY cityHash64(user_id) % 100 -- 100 партиций по хэшу user_id
|
||||
ORDER BY (log_time, id);
|
||||
|
||||
INSERT INTO dsolovianov.logs (id, user_id, log_time) VALUES
|
||||
(1, 123, '2024-07-17 10:00:00'),
|
||||
(2, 456, '2024-07-17 10:01:00'),
|
||||
(3, 789, '2024-07-17 10:02:00');
|
||||
|
||||
SELECT
|
||||
id,
|
||||
user_id,
|
||||
cityHash64(user_id) % 100 AS partition_number
|
||||
FROM dsolovianov.logs
|
||||
ORDER BY id;
|
||||
|
||||
SELECT * FROM logs WHERE user_id = 456;
|
||||
|
||||
|
||||
-- #4
|
||||
/*
|
||||
1. Создай таблицу с `PARTITION BY (region, toYYYYMM(visit_date))`.
|
||||
2. Как будет выглядеть имя партиции?
|
||||
Имена партиций будут в формате: ('значение_region', 'YYYYMM'). Пример: ('RU', '202406')
|
||||
3. Сможешь ли ты эффективно удалить **все июльские данные по `RU`**? Да. Удаляется целая партиция без сканирования и нагрузки на систему.
|
||||
*/
|
||||
|
||||
DROP TABLE IF EXISTS dsolovianov.visits ON CLUSTER clickhouse_cluster SYNC;
|
||||
|
||||
CREATE TABLE dsolovianov.visits
|
||||
ON CLUSTER clickhouse_cluster
|
||||
(
|
||||
id UInt64,
|
||||
region String,
|
||||
visit_date Date
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse/tables/{shard}/dsolovianov/visits',
|
||||
'{replica}'
|
||||
)
|
||||
PARTITION BY (region, toYYYYMM(visit_date))
|
||||
ORDER BY (region, visit_date, id);
|
||||
|
||||
INSERT INTO dsolovianov.visits (id, region, visit_date) VALUES
|
||||
(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');
|
||||
|
||||
ALTER TABLE dsolovianov.visits ON CLUSTER clickhouse_cluster
|
||||
DROP PARTITION ('RU', '202407');
|
||||
|
||||
SELECT * FROM dsolovianov.visits;
|
||||
Reference in New Issue
Block a user