| | 85 | {{{ |
| | 86 | CREATE OR REPLACE FUNCTION test_popular_courses() |
| | 87 | RETURNS void AS $$ |
| | 88 | DECLARE |
| | 89 | start_time timestamptz; |
| | 90 | end_time timestamptz; |
| | 91 | duration int; |
| | 92 | BEGIN |
| | 93 | start_time := clock_timestamp(); |
| | 94 | |
| | 95 | PERFORM |
| | 96 | c.id AS course_id, |
| | 97 | ct.title_short AS course_title, |
| | 98 | cv.version_number AS course_version, |
| | 99 | cv.active AS is_active, |
| | 100 | COUNT(DISTINCT e.id) AS total_enrollments, |
| | 101 | SUM(r.rating)::numeric / COUNT(r.id) AS average_rating, |
| | 102 | COUNT(r.id) AS total_reviews |
| | 103 | FROM course c |
| | 104 | JOIN course_translate ct ON c.id = ct.course_id |
| | 105 | JOIN course_version cv ON c.id = cv.course_id |
| | 106 | JOIN enrollment e ON cv.id = e.course_version_id |
| | 107 | JOIN review r ON e.id = r.enrollment_id |
| | 108 | WHERE ct.language = 'en' |
| | 109 | GROUP BY c.id, ct.id, cv.id |
| | 110 | ORDER BY SUM(r.rating)::numeric / COUNT(r.id) DESC |
| | 111 | LIMIT 20; |
| | 112 | |
| | 113 | end_time := clock_timestamp(); |
| | 114 | duration := round(1000 * (extract(epoch FROM end_time) - extract(epoch FROM start_time))); |
| | 115 | |
| | 116 | RAISE NOTICE 'Query executed in: % ms', duration; |
| | 117 | END; |
| | 118 | $$ LANGUAGE plpgsql; |
| | 119 | |
| | 120 | DROP INDEX IF EXISTS uk_course_translate_course_language; |
| | 121 | DROP INDEX IF EXISTS idx_course_version_course_id; |
| | 122 | DROP INDEX IF EXISTS idx_enrollment_course_version_id; |
| | 123 | DROP INDEX IF EXISTS uk_review_enrollment; |
| | 124 | |
| | 125 | -- run 1: no indexes |
| | 126 | |
| | 127 | SELECT test_popular_courses(); |
| | 128 | |
| | 129 | -- run 2: index uk_course_translate_course_language |
| | 130 | |
| | 131 | CREATE UNIQUE INDEX uk_course_translate_course_language |
| | 132 | ON course_translate(course_id, language); |
| | 133 | ANALYZE course_translate; |
| | 134 | |
| | 135 | SELECT test_popular_courses(); |
| | 136 | |
| | 137 | -- run 3: index uk_course_translate_course_language + idx_course_version_course_id |
| | 138 | |
| | 139 | CREATE INDEX idx_course_version_course_id |
| | 140 | ON course_version(course_id); |
| | 141 | ANALYZE course_version; |
| | 142 | |
| | 143 | SELECT test_popular_courses(); |
| | 144 | |
| | 145 | -- run 4: index uk_course_translate_course_language + idx_course_version_course_id + idx_enrollment_course_version_id |
| | 146 | |
| | 147 | CREATE INDEX idx_enrollment_course_version_id |
| | 148 | ON enrollment(course_version_id); |
| | 149 | ANALYZE enrollment; |
| | 150 | |
| | 151 | SELECT test_popular_courses(); |
| | 152 | |
| | 153 | -- run 5: all indexes -> uk_course_translate_course_language + idx_course_version_course_id + idx_enrollment_course_version_id + uk_review_enrollment |
| | 154 | |
| | 155 | CREATE UNIQUE INDEX IF NOT EXISTS uk_review_enrollment |
| | 156 | ON review(enrollment_id); |
| | 157 | ANALYZE review; |
| | 158 | |
| | 159 | SELECT test_popular_courses(); |
| | 160 | |
| | 161 | DROP FUNCTION test_popular_courses(); |
| | 162 | }}} |
| | 163 | |