added files theory bd with indexes and partitions

This commit is contained in:
Dmitry Medvedev
2026-07-09 23:38:46 +05:00
parent 6f96ed5510
commit f1e9502716
2 changed files with 372 additions and 0 deletions
+202
View File
@@ -0,0 +1,202 @@
- Задание 1: По каким полям делать индексы
Возьми таблицы из пет проекта “Онлайн магазин”.
**Ответь:**
1. По каким полям, как тебе кажется, реальный продукт‑менеджер или аналитик будет чаще всего:
- искать (`WHERE`),
по странам пользователя, по категориям техники, стомиость, возраст пользователей, статус заказа, активность пользователей.
- сортировать (`ORDER BY`),
количество заказов, стоимость, возраст пользователей, дата заказа.
- группировать (`GROUP BY`),
по пользователям, по возрасту пользователей, по дате заказа (когорты), по статусу заказа, по категориям.
- соединять (`JOIN`)?
по u.id, o.user_id, p.id, oi.order_id, oi.product_id
2. Для каждого поля, которое ты назвал, укажи: «индекс нужен / индекс не нужен» и коротко объясни почему (часто фильтруем, редко фильтруем, мало разных значений и т.п.).
по странам пользователя ДА
по категориям техники ДА
стомиость ДА
возраст пользователей НЕТ
статус заказа ДА
активность пользователей ДА
дата заказа ДА
по пользователям НЕТ
по u.id ДА
o.user_id ДА
p.id ДА
oi.order_id ДА
oi.product_id ДА
- Задание 2. Свяжи запрос и индекс
**Придумай и напиши по одному SQL‑запросу для ситуаций:**
1. Найти пользователя по `email`.
SELECT
name,
email
FROM users
WHERE email = '';
Здесь лучше всего подойдет индекс по email. Ускорит WHERE.
2. Показать всех активных пользователей (`is_active = true`), зарегистрированных за последний год (`created_at`).
SELECT
name ,
created_at
FROM users
WHERE is_active = TRUE AND created_at > now() - interval '1 year';
Здесь лучше всего подойдет индекс по is_active, created_at. Ускорит WHERE.
3. Показать все товары категории `'electronics'`, отсортированные по `price` от низкой к высокой.
SELECT
name ,
price
FROM products
WHERE category = 'electronics'
ORDER BY price ASC;
Здесь лучше всего подойдет индекс по category, price. Ускорит WHERE и ORDER BY.
4. Показать все заказы конкретного пользователя за последние 30 дней по `user_id` и `order_date`.
SELECT
id,
o.id AS order_id,
order_date
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE order_date > now() - interval '30 days' AND u.id = ;
Здесь лучше всего подойдет индекс по order_date, o.user_id, u.id. Ускорит JOIN и WHERE.
5. Для каждого заказа показать товары в нём (используя `order_items`).
SELECT
o.id AS order_id,
p.name AS product_name
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON p.id = oi.product_id;
Здесь лучше всего подойдут индексы по o.id, oi.order_id, p.id, oi.product_id. Ускорит JOIN.
**После этого:**
1. Для **каждого** запроса предложи **один индекс**, который поможет его ускорить.
2. Объясни словами: по каким полям индекс, в каком порядке (если их несколько) и какие части запроса он ускорит (`WHERE`, `JOIN`, `ORDER BY`).
***(Важно: сейчас не писать `CREATE INDEX` — только понять, какие индексы логичны.)***
- Задание 3. Порядок столбцов в индексе
Смотри на таблицу `orders`.
**Запросы:**
1. Все заказы пользователя за период:
WHERE user_id = ? AND order_date BETWEEN ? AND ?
2. Все заказы за период (без фильтра по пользователю):
WHERE order_date BETWEEN ? AND ?
3. Все заказы пользователя вообще:
WHERE user_id = ?
**Вопросы:**
1. Какой **один** составной индекс по полям `user_id` и `order_date` ты бы сделал (в каком порядке)?
CREATE INDEX idx_user_od ON orders(order_date, user_id)
2. Для каких из трёх запросов этот индекс будет работать особенно хорошо, а для каких — хуже? Объясни.
Для первого особенно хорошо, потому что будет по двух индексам.
Для остальных хуже потому что они фильтруют по одному индексу.
3. Сравни варианты:
- один индекс `(user_id, order_date)`
плюс: работает быстрее если сортируем по обоим столбцам
минус: не работает вообще если сортировать по order_date
- два индекса: `(user_id)` и `(order_date)`
плюс: гибкость
минус: требует больше места, иногда делает lookup
Напиши, в чём плюс и минус каждого подхода.
- Задание 4. Лишние индексы в наших таблицах
**Для каждой таблицы:**
1. users(...)
2. products(...)
3. orders(...)
4. order_items(...)
СКОРЕЕ НУЖЕН
u.id - связь по джойну и GROUP BY
u.age - можно применить в WHERE и ORDER BY
u.country - можно применить в WHERE и GROUP BY
u.is_active - можно применить в WHERE и GROUP BY
p.id - связь по джойну и GROUP BY
p.category - можно применить в WHERE и GROUP BY
p.price - можно применить в WHERE и ORDER BY
p.in_stock - можно применить в WHERE и GROUP BY
o.id - связь по джойну
o.user_id - связь по джойну и GROUP BY
o.status - можно применить в WHERE и GROUP BY
oi.order_id - связь по джойну и GROUP BY
oi.product_id - связь по джойну и GROUP BY
oi.price_at_purchase - можно применить в WHERE и ORDER BY
o.order_date - можно применить в WHERE и ORDER BY и GROUP BY
u.created_at - можно применить в WHERE и ORDER BY и GROUP BY
НА САМОМ ДЕЛЕ ИНДЕКСОВ ОЧЕНЬ МНОГО И ЛУЧШЕ КОНЕЧНО ИХ СОКРАТИТЬ, ЧТОБЫ БД МОГЛА БЫСТРЕЕ ВЫДАВАТЬ РЕЗУЛЬТАТ, ПОЭТОМУ ВЫБОР ДОБАВЛЕНИЯ ИЛИ УДАЛЕНИЯ ИНДЕКСА БУДЕТ ЗАВИСЕТЬ ОТ ПРОИЗВОДСТВЕННЫХ ЗАДАЧ.
СКОРЕЕ НЕ НУЖЕН
oi.quantity - не имеет смысла
p.name - не имеет смысла
u.email - все различны
u.name - не имеет смысла
Почему слишком много индексов замедляет INSERT, UPDATE и DELETE?
Индексы это средства для быстрого чтения данных, в этом они помогают. Но когда нам необзодимо добавить данные в таблицу, обновить или удалить, то в таком случае, БД должна будет и обратиться к индексам и их изменить тоже, поэтому слишком большое количество индексов в системе, которая предназначена для постоянного добавления/обновления данных, является негативным фактором.
**Сделай две группы столбцов:**
- «Скорее нужен индекс»
- «Скорее не нужен индекс»
И для **каждого** столбца, который ты туда попал, коротко напиши причину.
**В конце ответь текстом:** почему слишком много индексов замедляет INSERT, UPDATE и DELETE?
- Задание 5. Что должно быть уникальным
1. В таблице `users` выбери поля, которые должны быть уникальными в реальном проекте (например, `email`).
id, email
2. В таблице `products` выбери поле, которое в реальном магазине часто делают уникальным (например, какой‑то артикул — можешь придумать колонку `sku`, даже если её нет).
Например, это может быть поле name (например, айфон 15 про 128 гб серый) или как ты сказал артикул (sku)
3. Для каждого выбранного поля напиши:
- что будет, если уникальности не будет (какие реальные проблемы могут возникнуть);
В таком случае будет коллизия, задвоение или ошибка, например, человек покупает товар с определенным артикулом, в БД попадают данные о покупке товара с этим артикулом и случайно в заказ попадет два товара с одинаковым артиклом.
- почему вместо обычного индекса логичен **уникальный** индекс.
Чтобы случайно нельзя было добавить другой товар с таким же индексом. Разные индексы будут создавать уникальность для уникального товара.
- Задание 6. Где индексы помогут, а где нет
Для каждого запроса оцени: «индекс нужен / не нужен», и если нужен — по каким полям:
1. SELECT * FROM users WHERE id = 100; нужен по полю id
2. SELECT * FROM users WHERE email = 'user@example.com'; не нужен
3. SELECT * FROM products WHERE price BETWEEN 100 AND 500; нужен по price
4. SELECT * FROM products WHERE name LIKE '%phone%'; нужен по name
5. SELECT * FROM orders WHERE status = 'DELIVERED'; нужен по status
6. SELECT * FROM order_items WHERE order_id = 123; нужен по order_id
**Ответ — текстом:**
В чём выгода индекса и где он не поможет
Индекс помогает искать данные быстрее (индекс это как содержание в книге). Индекс не поможет в тех столбцах, где все данные в столбце различаются, например email.