added theory bd b-tree and hash indexes

This commit is contained in:
Dmitry Medvedev
2026-07-11 17:52:38 +05:00
parent cad40d4a0c
commit cfb837fcbf
@@ -0,0 +1,104 @@
- Задание 1:
**Дана таблица:**
users(id PK, email, age, created_at)
**И индекс:**
CREATE INDEX idx_users_email ON users(email);
**Ответь для каждого варианта:**
- будет ли использоваться этот индекс;
- если нет — что нужно изменить (индекс или запрос).
**Варианты:**
1. SELECT * FROM users WHERE email = 'test@example.com'; // будет, менять ничего не нужно
2. SELECT * FROM users WHERE LOWER(email) = 'test@example.com'; // не будет, нужно изменить запрос, а именно убрать функцию LOWER
3. SELECT * FROM users WHERE email LIKE 'alex%'; // будет, все норм
4. SELECT * FROM users WHERE email LIKE '%@gmail.com'; // не будет, так как ищем оканчание строки. не знаю что тут можно поменять, как-будто ничего
5. SELECT * FROM users ORDER BY email LIMIT 10; // будет, все норм
6. SELECT * FROM users WHERE age BETWEEN 20 AND 30; // будет, все норм, но только B-tree
- Задание 2:
**Дана таблица заказов:**
orders(
id PK,
user_id,
status,
created_at,
amount
);
**К каждому запросу нужно сказать, что индекс не нужен/бесполезен):**
1. История заказов пользователя за период:
SELECT *
FROM orders
WHERE user_id = 123
AND created_at BETWEEN '2025-01-01' AND '2025-02-01'
ORDER BY created_at;
2. Ежедневная агрегация по статусу:
SELECT date_trunc('day', created_at) AS day,
status,
count(*)
FROM orders
GROUP BY day, status;
3. Проверка наличия хотя бы одного «висящего» заказа:
SELECT 1
FROM orders
WHERE status = 'pending'
LIMIT 1;
**Напиши `CREATE INDEX ...` и объясни, почему такой порядок колонок**
1. CREATE INDEX idx_orders_user_id_created_at ON orders (user_id, created_at)
ТАК ЭФФЕКТИВНЕЕ ПОТОМУ ЧТО СНАЧАЛА НАХОДИТСЯ ПОЛЬЗОВАТЕЛЕЙ, А ПОТОМ ДИАПАЗОН ЕГО ДАТ. ИНАЧЕ ПРИШЛОСЬ БЫ СНАЧАЛА ФИЛЬТРОВАТЬ ДИАПАЗОН ДАТ, А ПОТОМ НЕ НУЖНЫХ ПОЛЬЗОВАТЕЛЕЙ.
2. В ДАННОМ СЛУЧАЕ ИНДЕКС НЕ НУЖЕН ПОТОМУ ЧТО НЕТ УСЛОВИЯ В КОДЕ, ПОСТГРЕ ПРИДЕТСЯ В ЛЮБОМ СЛУЧАЕ СМОТРЕТЬ ВСЮ ТАБЛИЦУ.
3. CREATE INDEX idx_status_peding ON orders (status) WHERE status = 'pending'
ЗДЕСЬ МОЖНО ИСПОЛЬЗОВАТЬ ИНДЕКС ТОЛЬКО ПО ОДНОМУ ПОЛЮ "pending" ЧТОБЫ НЕ ИНДЕКСИРОВАТЬ ВСЕ ЗНАЧЕНИЯ ПО ДАННОМУ СТОЛБЦУ status
- Задание 3:
Та же таблица `orders`
**Выбери тип индекса и объясни почему выбрал такой для вариантов:**
1. SELECT * FROM orders WHERE id = 100500; // hash , возможное соединение таблиц
2. SELECT * FROM orders WHERE status = 'paid'; // спорен
3. SELECT * FROM orders WHERE created_at BETWEEN ...; // только B-tree из-за диапазона
4. SELECT * FROM orders WHERE user_id = 123; // hash, возможное соединение таблиц
**Вопросы:**
- Где hash имел бы смысл?
- Где обязательно B‑tree?
- Где индекс вообще спорен?
- Задание 4:
**Исходные индексы:**
CREATE INDEX idx_orders_user_created ON orders(user_id, created_at);
CREATE INDEX idx_orders_user ON orders(user_id);
**Задача:**
- объяснить, зачем нужен первый;
ЧТОБЫ ОДНОВРЕМЕННО ИСКАТЬ ПОЛЬЗОВАТЕЛЕЙ В СОВОКУПНОСТИ С ДАТОЙ СОЗДАНИЯ. И ТАКЖЕ СОРТИРОВАТЬ ПО ДАТЕ СОЗДАНИЯ ПОЛЬЗОВАТЛЕЙ .
- нужен ли второй или его можно удалить;
ВТОРОЙ НЕ НУЖЕН, ПОТОУ ЧТО ПЕРВЫЙ МОЖЕТ РАБОТАТЬ ПО ЛЕВОМУ ПРЕФИКСУ. ВТОРОЙ ИНДЕКС ЛИШЬ ЗАНИМАЕТ ЛИШНЕЕ МЕСТО.