115 lines
3.9 KiB
SQL
115 lines
3.9 KiB
SQL
# Задачи на отработку:
|
||
|
||
### **Задача 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%'`?
|
||
В ТАКОМ СЛУЧАЕ ОБЫКНОВЕННЫЙ ФИЛЬТР БЛУМА СРАБОТАЕТ. |