- **Задача 1** — Когда какой метод? ✅ Заполни таблицу: | **Ситуация** | **Какой JOIN выберет база?** | **Почему?** | | --- | --- | --- | | 10 пользователей, 1 млн заказов, есть индекс на orders.user_id | Nested Loop | Потому что есть индекс по одному полю и одна таблица мееьше другой сильно | | 100 000 пользователей, 100 000 заказов, нет индексов | Hash Join | Нет ни индексов, ни сортировки | | Обе таблицы отсортированы по ключу, есть индексы | Merge Join | Потому что есть и индексы и сортировка | | Маленькая таблица (5 строк) соединяется с большой (1 млн строк), нет индекса | Hash Join | Потому что нет индекса | - **Задача 2** — Размер таблиц имеет значение ✅ Создай тестовые данные: -- Маленькая таблица (10 строк) CREATE TABLE small_users AS SELECT generate_series(1, 10) AS id, 'User ' || generate_series(1, 10) AS name; -- Большая таблица (100 000 строк) CREATE TABLE big_orders AS SELECT generate_series(1, 100000) AS id, (random() * 9 + 1)::int AS user_id, CURRENT_DATE - (random() * 365)::int AS order_date; ✅ Теперь выполни: -- Вариант 1: Без индекса EXPLAIN ANALYZE SELECT u.name, COUNT(o.id) FROM small_users u JOIN big_orders o ON u.id = o.user_id GROUP BY u.name; -- Вариант 2: С индексом CREATE INDEX idx_big_orders_user_id ON big_orders(user_id); EXPLAIN ANALYZE SELECT u.name, COUNT(o.id) FROM small_users u JOIN big_orders o ON u.id = o.user_id GROUP BY u.name; **❓ Вопросы:** 1. Какой метод `JOIN` используется в каждом случае? В обоих случаях у меня показало Merge Join, просто там где индекс - там Scan Index. 2. Почему с индексом база может выбрать `Nested Loop`? Потому что будет маленькая таблица, иногда проще заджойнить большую и маленькую Nested Loop. 3. Насколько быстрее стало с индексом? В 2,5 раза. - **Задача 3** — Влияние сортировки ✅ Выполни три варианта: -- Вариант 1: Без ORDER BY EXPLAIN ANALYZE SELECT u.name, o.order_date FROM users u JOIN orders o ON u.id = o.user_id; -- Вариант 2: С ORDER BY по ключу соединения EXPLAIN ANALYZE SELECT u.name, o.order_date FROM users u JOIN orders o ON u.id = o.user_id ORDER BY u.id, o.user_id; -- Вариант 3: С ORDER BY по другому полю EXPLAIN ANALYZE SELECT u.name, o.order_date FROM users u JOIN orders o ON u.id = o.user_id ORDER BY o.order_date; **❓Вопросы:** 1. Изменился ли тип `JOIN` во втором варианте? В первом Hash, во втором - Merge. 2. Появился ли `Merge Join`? Да. 3. Почему `ORDER BY` может повлиять на выбор `JOIN`? Потому что появляется метод при соединении (при условии наличия order by), упрощающий join. - **Задача 4** — Найди узкое место ✅ Дан медленный запрос: SELECT u.name, p.name AS product_name, oi.quantity, o.order_date FROM users u JOIN orders o ON u.id = o.user_id JOIN order_items oi ON o.id = oi.order_id JOIN products p ON oi.product_id = p.id WHERE u.country = 'Россия'; **✅ Задание:** 1. Выполни с `EXPLAIN ANALYZE` 2. Посмотри, какие типы `JOIN` используются Nested Loop and Hash Join. 3. Есть ли `Seq Scan`? Если да — где? Да, в трех местах. При чтении таблицы users, orders и products. 4. Предложи, какие индексы нужно создать Можно создать 3 индекса 5. Создай индексы и проверь, изменились ли типы `JOIN` Изменились, но не сильно, в основном все Hash, один внешний Nested - **Задача 5** — Многоступенчатый JOIN EXPLAIN ANALYZE SELECT u.name, COUNT(DISTINCT o.id) AS orders_count, COUNT(DISTINCT oi.product_id) AS products_count FROM users u LEFT JOIN orders o ON u.id = o.user_id LEFT JOIN order_items oi ON o.id = oi.order_id WHERE u.country = 'Россия' GROUP BY u.name; **✅ Задание:** 1. Посмотри на план выполнения 2. Какие методы `JOIN` используются на каждом уровне? Hash right join 2 раза 3. Почему для первого `JOIN` один метод, а для второго — другой? У меня оба одинаковые, вероятнее всего из-за неверных индексов или чего-то другого. 4. Сколько строк проходит через каждый `JOIN`? По одной - **Задача 6** — `LEFT JOIN` vs `INNER JOIN` ✅ Сравни два запроса: -- Вариант A: INNER JOIN EXPLAIN ANALYZE SELECT u.name, o.order_date FROM users u INNER JOIN orders o ON u.id = o.user_id; -- Вариант B: LEFT JOIN EXPLAIN ANALYZE SELECT u.name, o.order_date FROM users u LEFT JOIN orders o ON u.id = o.user_id; **❓ Вопросы:** 1. Одинаковый ли тип физического JOIN используется? Hash and Hash Right 2. Есть ли разница в Execution Time? Не сильно , скачет то в одну, то в другую сторону 3. Почему LEFT JOIN может быть медленнее? - **Задача 7** — Порядок таблиц в JOIN ✅ Сравни: -- Вариант 1: users JOIN orders EXPLAIN ANALYZE SELECT u.name, o.order_date FROM users u JOIN orders o ON u.id = o.user_id; -- Вариант 2: orders JOIN users EXPLAIN ANALYZE SELECT u.name, o.order_date FROM orders o JOIN users u ON o.user_id = u.id; **❓ Вопросы:** 1. Изменился ли тип `JOIN`? нет 2. Изменился ли порядок чтения таблиц в плане? нет 3. Одинаковое ли `Execution Time`? Да 4. Почему оптимизатор может выбрать разный порядок? потому чтт ему будет так проще соединять таблицы и читать данные