added task greenplun zaprosi

This commit is contained in:
Dmitry Medvedev
2026-07-12 22:28:05 +05:00
parent 3177c7cda5
commit f1e8d5765f
+90
View File
@@ -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;
**Вопросы:**
- Какие ключевые слова ты хочешь увидеть в плане?
ПОКА ЗАТРУДНЯЮСЬ ОТВЕТИТЬ НА ДАННЫЙ ВОПРОС, ЕЩЕ НЕ РАЗОБРАЛСЯ В ТЕМЕ ДО КОНЦА.