-- Индексы и сжатие - Индексы -- -- #1 /* 3. Посмотри, сколько блоков было пропущено (в `system.query_log`, `rows_read`, `rows`). Не посмотрю, так как нет доступа system.query_log, rows_read, rows (ACCESS_DENIED) 4. Что будет, если `ORDER BY log_id`, а не `ts`? ORDER BY log_id → данные физически отсортированы по log_id. Значения ts расположены хаотично относительно физической сортировки. Индекс minmax по ts будет почти бесполезен. Minmax индекс будет иметь широкие диапазоны */ DROP TABLE IF EXISTS dsolovianov.logs ON CLUSTER clickhouse_cluster SYNC; CREATE TABLE dsolovianov.logs ON CLUSTER clickhouse_cluster ( log_id UInt64, ts DateTime ) ENGINE = ReplicatedMergeTree( '/clickhouse/tables/{shard}/dsolovianov/logs', '{replica}' ) ORDER BY ts PARTITION BY toYYYYMM(ts) PRIMARY KEY (ts); INSERT INTO dsolovianov.logs (log_id, ts) VALUES (1, '2024-06-01 10:00:00'), (2, '2024-06-01 11:00:00'), (3, '2024-06-02 12:00:00'), (4, '2024-06-03 13:00:00'), (5, '2024-06-04 14:00:00'); -- 1. Добавляем minmax индекс: ALTER TABLE dsolovianov.logs ADD INDEX idx_ts ts TYPE minmax GRANULARITY 2; -- 2. Сделай запрос: `SELECT * FROM logs WHERE ts BETWEEN '2024-06-02' AND '2024-06-03'` SELECT * FROM dsolovianov.logs WHERE ts BETWEEN '2024-06-02' AND '2024-06-03'; -- Раз нет доступа, но можно предположить, что вот такой запрос сработает: SELECT query, read_rows, result_rows FROM system.query_log WHERE query LIKE '%logs%' ORDER BY event_time DESC LIMIT 1; -- #2 /* 1. Создай таблицу с `ORDER BY id`, добавь индекс: ```sql ALTER TABLE clicks ADD INDEX idx_country country TYPE set(1000) GRANULARITY 2; ``` 3. Посмотри `EXPLAIN` — индекс используется? Данные отсортированы по id, а не по country. Значения country распределены хаотически относительно физического порядка. 4. Как будет вести себя индекс, если `country` имеет 10M уникальных значений? Будет создано 10M партиций, что убьёт производительность. **/ DROP TABLE IF EXISTS dsolovianov.clicks ON CLUSTER clickhouse_cluster SYNC; CREATE TABLE dsolovianov.clicks ON CLUSTER clickhouse_cluster ( id UInt64, country String ) ENGINE = ReplicatedMergeTree( '/clickhouse/tables/{shard}/dsolovianov/clicks', '{replica}' ) ORDER BY id PARTITION BY country PRIMARY KEY (id); INSERT INTO dsolovianov.clicks (id, country) VALUES (1, 'RU'), (2, 'US'), (3, 'RU'), (4, 'DE'), (5, 'RU'); ALTER TABLE dsolovianov.clicks ON CLUSTER clickhouse_cluster ADD INDEX idx_country country TYPE set(1000) GRANULARITY 2; -- 2. Выполни запрос `SELECT * FROM clicks WHERE country = 'RU'`. EXPLAIN indexes = 1 SELECT * FROM dsolovianov.clicks WHERE country = 'RU'; EXPLAIN SELECT * FROM dsolovianov.clicks WHERE country = 'RU'; /* Expression ((Project names + Projection)) Expression ((WHERE + Change column names to column identifiers)) ReadFromMergeTree (dsolovianov.clicks) Indexes: MinMax Keys: country Condition: (country in ['RU', 'RU']) Parts: 1/3 Granules: 1/3 Partition Keys: country Condition: (country in ['RU', 'RU']) Parts: 1/1 Granules: 1/1 PrimaryKey Condition: true Parts: 1/1 Granules: 1/1 Skip Name: idx_country Description: set GRANULARITY 2 Parts: 1/1 Granules: 1/1 Ranges: 1 */ -- #3 DROP TABLE IF EXISTS dsolovianov.users ON CLUSTER clickhouse_cluster SYNC; CREATE TABLE dsolovianov.users ON CLUSTER clickhouse_cluster ( id UInt64, email String ) ENGINE = ReplicatedMergeTree( '/clickhouse/tables/{shard}/dsolovianov/users', '{replica}' ) ORDER BY id PRIMARY KEY (id); INSERT INTO dsolovianov.users (id, email) VALUES (1, 'alice@mail.com'), (2, 'bob@mail.com'), (3, 'charlie@mail.com'), (4, 'dave@mail.com'), (5, 'eve@example.com'); ALTER TABLE dsolovianov.users ADD INDEX idx_email email TYPE bloom_filter(0.01) GRANULARITY 2; EXPLAIN indexes = 1 SELECT * FROM users WHERE email = 'alice@mail.com'; -- Bloom filter может пропустить некоторые гранулы, но не все, ибо данные не отсортированы по email и индексные блоки покрывают случайные email'ы EXPLAIN indexes = 1 SELECT * FROM users WHERE email LIKE '%mail%'; EXPLAIN indexes = 1 SELECT * FROM users WHERE email LIKE 'alice%'; /* Bloom filter не поддерживает частичные совпадения (LIKE '..%', LIKE '%..', LIKE '%..%'). Из-за этого ClickHouse не может пропустить гранулы. Клику становится сложно вычислить хэш для проверки, если подходящих значений по LIKE будет больше одного. Нет гарантии, что данные на выходе будут корректные. */