# Задачи на отработку: ### **Задача 1.** **Таблица:** `logs(log_id UInt64, ts DateTime)` | log_id | ts | | --- | --- | | 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. Создай `ORDER BY ts`, добавь `minmax`индекс: ALTER TABLE logs ADD INDEX idx_ts ts TYPE minmax GRANULARITY 2; ГОТОВО 2. Сделай запрос: `SELECT * FROM logs WHERE ts BETWEEN '2024-06-02' AND '2024-06-03'` ГОТОВО 3. Посмотри, сколько блоков было пропущено (в `system.query_log`, `rows_read`, `rows`). НЕТ ПРАВ ДОСТУПА 4. Что будет, если `ORDER BY log_id`, а не `ts`? ТОГДА ДАННЫЕ НА ДИСКЕ БУДУТ ОТСОРТИРОВАНЫ ПО log_id, а первичный и вторичный индексы по ts перестанут помогать в поиске данных. ### **Задача 2.** **Таблица:** `clicks(id UInt64, country String)` | id | country | | --- | --- | | 1 | RU | | 2 | US | | 3 | RU | | 4 | DE | | 5 | RU | 1. Создай таблицу с `ORDER BY id`, добавь индекс: ALTER TABLE clicks ADD INDEX idx_country country TYPE set(1000) GRANULARITY 2; ДОБАВИЛ 2. Выполни запрос `SELECT * FROM clicks WHERE country = 'RU'`. ВЫПОЛНИЛ 3. Посмотри `EXPLAIN` — индекс используется? ИСПОЛЬЗУЕТСЯ Expression ((Project names + Projection)) Expression ((WHERE + Change column names to column identifiers)) ReadFromMergeTree (dmedvedev.clicks) Indexes: 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 4. Как будет вести себя индекс, если `country` имеет 10M уникальных значений? ОН НЕ БУДЕТ РАБОТАЬ, ТАК КАК МЫ ИНДЕКСЕ set МЫ УСТАНОВИЛИ ПОРОГ УНИКАЛЬНЫХ ЗНАЧЕНИЙ В 1000 ШТУК. В ТАКИХ СЛУЧАЯХ НУЖНО БЫЛО БЫ ВОСПОЛЬЗОВАТЬСЯ БЛУМ ФИЛЬТРОМ. ### **Задача 3.** **Таблица:** `users(id UInt64, email String)` | id | email | | --- | --- | | 1 | alice@mail.com | | 2 | bob@mail.com | | 3 | charlie@mail.com | | 4 | dave@mail.com | | 5 | eve@example.com | 1. Добавь индекс: ALTER TABLE users ADD INDEX idx_email email TYPE bloom_filter(0.01) GRANULARITY 2; ДОБАВИЛ 2. Проверь поиск по точному email: SELECT * FROM users WHERE email = 'alice@mail.com'; РАБОТАЕТ 1 alice@mail.com Expression ((Project names + Projection)) Expression ((WHERE + Change column names to column identifiers)) ReadFromMergeTree (dmedvedev.users) Indexes: PrimaryKey Condition: true Parts: 1/1 Granules: 1/1 Skip Name: idx_email Description: bloom_filter GRANULARITY 2 Parts: 1/1 Granules: 1/1 Ranges: 1 3. Почему этот индекс **не ускоряет** поиск по `LIKE '%mail%'`? ПОТОМУ ЧТО ФИЛЬТР БЛУМА НЕ МОЖЕТ ИСКАТЬ ДАННЫЕ КОТОРЫЕ СОДЕРЖАТЬСЯ ВНУТРИ КАКИХ-ТО СТРОК, ЕМУ НУЖНО ПОНИМАТЬ КАКОЕ БУДЕТ НАЧАЛО, А ЗДЕСЬ ОНО НЕ УКАЗАНО. ДЛЯ ТАКОГО ПОИСКА НУЖНО ПРИМЕНЯТЬ МОДЕРНИЗИРОВАННЫЙ ФИЛЬТР БЛУМА ПО ТОКЕНАМ. 4. Что произойдёт при `LIKE 'alice%'`? В ТАКОМ СЛУЧАЕ ОБЫКНОВЕННЫЙ ФИЛЬТР БЛУМА СРАБОТАЕТ.