Files
homework/dmedvedev/clickhouse/7.CH_indexes.sql
T

115 lines
3.9 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Задачи на отработку:
### **Задача 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%'`?
В ТАКОМ СЛУЧАЕ ОБЫКНОВЕННЫЙ ФИЛЬТР БЛУМА СРАБОТАЕТ.