58 lines
2.4 KiB
SQL
58 lines
2.4 KiB
SQL
-- Задание 1: Анализ drop-off точек
|
|
SELECT
|
|
cf.course_id,
|
|
c.title AS course_title,
|
|
cf.stage_name,
|
|
cf.users_count,
|
|
ROUND(100 - cf.conversion_from_previous, 2) AS dropoff_percentage
|
|
FROM dmezentsev.conversion_funnel cf
|
|
JOIN dmezentsev.courses c ON cf.course_id = c.id
|
|
WHERE cf.stage_name = 'started'
|
|
ORDER BY dropoff_percentage DESC;
|
|
|
|
-- Задание 2: Топ-3 урока с повторными просмотрами
|
|
SELECT
|
|
lesson_id,
|
|
lesson_title,
|
|
course_title,
|
|
total_views,
|
|
unique_viewers,
|
|
avg_views_per_viewer,
|
|
popularity_rank
|
|
FROM dmezentsev.lesson_popularity_ranking
|
|
WHERE avg_views_per_viewer > 1
|
|
ORDER BY avg_views_per_viewer DESC, total_views DESC;
|
|
|
|
-- Задание 3: Лучшая когорта по retention
|
|
SELECT cohort_month, retention_rate
|
|
FROM user_cohort_analysis
|
|
ORDER BY retention_rate DESC
|
|
LIMIT 3;
|
|
|
|
|
|
-- Задание 4: Найди узкие места: Seq Scan, высокие cost, JOIN без индексов, DISTINCT, подзапросы в SELECT.
|
|
|
|
/* EXPLAIN ANALYZE:
|
|
|
|
Seq Scan on conversion_funnel (cost=0.00..11.40 rows=140 width=530) (actual time=0.007..0.011 rows=25 loops=1)
|
|
Planning Time: 0.124 ms
|
|
Execution Time: 0.027 ms
|
|
|
|
+- по каждой вьюхе такой план:
|
|
rows=25, rows=5, rows=18 — очень мало данных
|
|
Execution Time везде маленький (0.027 - 0.330 ms)
|
|
Seq Scan — потому что таблицы небольшие
|
|
|
|
Не придумал на данный момент, как улучшить запросы, но для ускорения запросов на больших данных
|
|
ввел бы индексацию внешних ключей
|
|
*/
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_enrollments_user_id ON dmezentsev.enrollments(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_enrollments_course_id ON dmezentsev.enrollments(course_id);
|
|
CREATE INDEX IF NOT EXISTS idx_lessons_course_id ON dmezentsev.lessons(course_id);
|
|
CREATE INDEX IF NOT EXISTS idx_lesson_views_user_id ON dmezentsev.lesson_views(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_lesson_views_lesson_id ON dmezentsev.lesson_views(lesson_id);
|
|
CREATE INDEX IF NOT EXISTS idx_lesson_views_viewed_at ON dmezentsev.lesson_views(viewed_at);
|
|
|
|
-- А также создал бы индекс для даты регистрации
|
|
CREATE INDEX IF NOT EXISTS idx_users_registration_date ON dmezentsev.users_(registration_date); |