diff --git a/dmedvedev/4.1.greenplum_zaplosi.sql b/dmedvedev/4.1.greenplum_zaplosi.sql new file mode 100644 index 0000000..0afab42 --- /dev/null +++ b/dmedvedev/4.1.greenplum_zaplosi.sql @@ -0,0 +1,90 @@ +### Задача 1: + +SELECT * FROM orders ORDER BY total DESC LIMIT 10; + +Таблица `orders` содержит **10 млн строк**, распределена по `user_id`. + +- 📌 Что произойдёт? Почему это может тормозить? + - **Визуализация** + + Segment 1 → 2M строк + Segment 2 → 2M строк + Segment 3 → 2M строк + Segment 4 → 2M строк + Segment 5 → 2M строк + + ▼ + Gather to master + ▼ + LIMIT 10 применяется только тут + + +**Задание:** + +- Предложи способ ускорить выборку топ-N с предварительной агрегацией/фильтрацией. + ЕСЛИ РАБОТАТЬ ПО ТАКОМУ ЗАПРОСУ, ТО КАЖДЫЙ СЛЭЙВ СНАЧАЛА ВЫДЕЛИТ 10 ТОП ЗНАЧЕНИЙ И ОТПРАВИТ НА МАСТЕР, ПОЛУЧИТСЯ 50 СТРОК. + В ИДЕАЛЕ ЕСЛИ ДЕЛАЕМ ORDER BY ПО total, ТО НУЖНО СДЕЛАТЬ ИНДЕКС ПО ПОЛЮ total, ЧТОБЫ НЕ ЧИТАЛИСЬ ВСЕ ТАБЛЛИЦЫ, А ТАКЖЕ ВМЕСТО * УКАЗАТЬ НЕОБХОДИМЫЕ СТОЛБЦЫ. + +### Задача 2: + +SELECT + user_id, + total, + RANK() OVER (PARTITION BY region_id ORDER BY total DESC) as rnk +FROM orders; + +- 📌 Что не так? Какие издержки? + - **Визуализация:** + + ``` + orders распределены по user_id + ▼ + окно работает по region_id → данные перегоняются между сегментами! + ``` + + +**Вопрос:** + +- Как лучше распределить таблицу, если часто используешь оконные по `region_id`? + ДУМАЮ В ЭТОМ СЛУЧАЕ МОЖНО ПОМЕНЯТЬ destributed by по region_id ИЛИ МОЖНО СОСТАВНОЙ КЛЮЧ ПО region_id, user_id + +### Задача 3: + +INSERT INTO top_users +SELECT user_id, SUM(total) as total_spent +FROM orders +GROUP BY user_id; + +Но `top_users DISTRIBUTED BY (user_id)`, а `orders DISTRIBUTED BY (order_id)`. + +**Что произойдёт?** + +- 📌 Подсказка: + + Greenplum будет пересылать строки между сегментами. + + - **Визуализация:** + + ``` + Segment A: SUM(user_id=1) → отправить в другой сегмент (там находится user_id=1 в top_users) + Segment B: SUM(user_id=2) → ... + ``` + + +**Задание:** + +- Предложи, как перераспределить `orders`, чтобы вставка была без motion. + В ТАКОМ СЛУЧАЕ ЛУЧШЕ ПЕРЕДЕЛАТЬ РАСПРЕДЕЛЕНИЕ orders НА DISTRIBUTED BY (user_id) ПО ОБЕИМ ТАБЛИЦАМ. + +### Задача 4: + +Ты пишешь: + +EXPLAIN SELECT u.name, o.total +FROM users u +JOIN orders o ON u.user_id = o.user_id; + +**Вопросы:** + +- Какие ключевые слова ты хочешь увидеть в плане? + ПОКА ЗАТРУДНЯЮСЬ ОТВЕТИТЬ НА ДАННЫЙ ВОПРОС, ЕЩЕ НЕ РАЗОБРАЛСЯ В ТЕМЕ ДО КОНЦА. \ No newline at end of file