-- Индексы и сжатие - Партиции -- -- #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;