| 67 | | === Резултати пред и по индексите |
| 68 | | |
| 69 | | || '''Барање''' || '''Пред''' || '''По''' || '''Промена''' || |
| 70 | | || Извештај 1 - проодност по предмет || 146,0 ms || 156,0 ms || нема || |
| 71 | | || Извештај 2 - досие на сите студенти || 188,5 ms || 179,4 ms || нема || |
| 72 | | || Извештај 3 - најуспешен студент по програма || 107,3 ms || 94,0 ms || нема || |
| 73 | | || Извештај 4 - најоптоварен професор || 121,9 ms || 124,6 ms || нема || |
| 74 | | || Извештај 5 - промена на активноста || 124,0 ms || 138,1 ms || нема || |
| 75 | | || Досие на '''еден''' студент || 2,19 ms || '''1,07 ms''' || '''2,0 пати побрзо''' || |
| 76 | | || Дневник на професор за еден професор || 16,3 ms || '''7,6 ms''' || '''2,1 пати побрзо''' || |
| 77 | | |
| 78 | | === Зошто петте извештаи не станаа побрзи |
| 79 | | |
| 80 | | Ова не е неуспех на индексите, туку очекувано однесување. Петте извештаи од Фаза |
| 81 | | 6 се агрегатни - тие читаат '''сè''' од semesters_subjects, passed_subjects и |
| | 67 | === Кои прашалници се анализирани |
| | 68 | |
| | 69 | Анализирани се седум прашалници. Шест од нив се '''точно извештаите од |
| | 70 | Фаза 6''' (види [wiki:AdvancedReports AdvancedReports], скрипта [attachment:reports.sql]), |
| | 71 | а седмиот е секојдневно барање на апликацијата, додаден за споредба. |
| | 72 | |
| | 73 | || '''#''' || '''Прашалник''' || '''Извор''' || '''Рутина во reports.sql''' || |
| | 74 | || 1 || Проодност по предмет и семестар || Фаза 6, Извештај 1 || {{{rep_subject_pass_rate()}}} || |
| | 75 | || 2 || Досие на сите студенти || Фаза 6, Извештај 2 || {{{rep_student_dossier()}}} || |
| | 76 | || 3 || Најуспешен студент по програма || Фаза 6, Извештај 3 || {{{rep_top_student_per_major()}}} || |
| | 77 | || 4 || Најоптоварен професор по семестар || Фаза 6, Извештај 4 || {{{rep_busiest_professor()}}} || |
| | 78 | || 5 || Промена на активноста меѓу семестри || Фаза 6, Извештај 5 || {{{rep_semester_growth()}}} || |
| | 79 | || 6 || Досие на '''еден''' студент || Фаза 6, Извештај 2 со аргумент || {{{rep_student_dossier(2500)}}} || |
| | 80 | || 7 || Дневник на професор || Апликација (не е од Фаза 6) || — || |
| | 81 | |
| | 82 | Извештај 2 е мерен '''двапати''': еднаш без аргумент, кога враќа секој студент, и |
| | 83 | еднаш со p_user_id = 2500, кога враќа еден. Истата рутина со два различни |
| | 84 | аргумента покажува дека одлучувачки е '''селективноста''', а не самото барање. |
| | 85 | |
| | 86 | Точните наредби со кои се мерени се во [attachment:queries.sql]. |
| | 87 | |
| | 88 | === Методологија на мерењето |
| | 89 | |
| | 90 | За секој прашалник се снимени планови за извршување '''двапати''': |
| | 91 | |
| | 92 | 1. врз шема без дополнителни индекси — датотеки {{{before_*.txt}}} |
| | 93 | 2. по извршување на [attachment:indexes.sql] и {{{ANALYZE}}} — датотеки {{{after_*.txt}}} |
| | 94 | |
| | 95 | Сите четиринаесет излези се приложени кон оваа страна во целост. Подолу е |
| | 96 | даден извадок од секој план — точно оние јазли каде се гледа дали индексот |
| | 97 | се употребува или не. |
| | 98 | |
| | 99 | === Збирен преглед |
| | 100 | |
| | 101 | || '''#''' || '''Прашалник''' || '''Пред''' || '''По''' || '''Планот се промени?''' || |
| | 102 | || 1 || rep_subject_pass_rate || 146,0 ms || 156,0 ms || '''Не''' - идентичен план || |
| | 103 | || 2 || rep_student_dossier() || 188,5 ms || 179,4 ms || '''Не''' - идентичен план || |
| | 104 | || 3 || rep_top_student_per_major || 107,3 ms || 94,0 ms || '''Не''' - идентичен план || |
| | 105 | || 4 || rep_busiest_professor || 121,9 ms || 124,6 ms || '''Не''' - идентичен план || |
| | 106 | || 5 || rep_semester_growth || 124,0 ms || 138,1 ms || '''Не''' - идентичен план || |
| | 107 | || 6 || rep_student_dossier(2500) || 2,19 ms || '''1,07 ms''' || '''Да''' - Seq Scan ⇒ Index Scan || |
| | 108 | || 7 || Дневник на професор || 16,3 ms || '''7,6 ms''' || '''Да''' - Seq Scan ⇒ Bitmap Index Scan || |
| | 109 | |
| | 110 | Последната колона е докажана подолу за секој прашалник посебно. |
| | 111 | |
| | 112 | === Прашалник 1 - проодност по предмет (Фаза 6, Извештај 1) |
| | 113 | |
| | 114 | {{{#!sql |
| | 115 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM rep_subject_pass_rate(); |
| | 116 | }}} |
| | 117 | |
| | 118 | '''План ПРЕД индексите''' ([attachment:before_rep_subject_pass_rate.txt]): |
| | 119 | |
| | 120 | {{{ |
| | 121 | -> Seq Scan on semesters_subjects ss (rows=80000) (actual time=0.007..3.658 rows=80000.00) |
| | 122 | -> Seq Scan on passed_subjects ps (rows=56000) (actual time=0.011..4.648 rows=56000.00) |
| | 123 | -> Seq Scan on enrolled_semesters es (rows=16000) (actual time=0.011..2.191 rows=16000.00) |
| | 124 | Execution Time: 146.018 ms |
| | 125 | }}} |
| | 126 | |
| | 127 | '''План ПО индексите''' ([attachment:after_rep_subject_pass_rate.txt]): |
| | 128 | |
| | 129 | {{{ |
| | 130 | -> Seq Scan on semesters_subjects ss (rows=80000) (actual time=0.007..4.131 rows=80000.00) |
| | 131 | -> Seq Scan on passed_subjects ps (rows=56000) (actual time=0.014..5.114 rows=56000.00) |
| | 132 | -> Seq Scan on enrolled_semesters es (rows=16000) (actual time=0.011..2.333 rows=16000.00) |
| | 133 | Execution Time: 156.015 ms |
| | 134 | }}} |
| | 135 | |
| | 136 | '''Заклучок:''' планот е идентичен — во него '''не се појавува ниту еден''' од |
| | 137 | новите индекси. Барањето агрегира врз целите табели, па планерот точно |
| | 138 | заклучува дека секвенцијалното читање е поевтино. |
| | 139 | |
| | 140 | === Прашалник 2 - досие на сите студенти (Фаза 6, Извештај 2) |
| | 141 | |
| | 142 | {{{#!sql |
| | 143 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM rep_student_dossier(); |
| | 144 | }}} |
| | 145 | |
| | 146 | '''План ПРЕД индексите''' ([attachment:before_rep_student_dossier.txt]): |
| | 147 | |
| | 148 | {{{ |
| | 149 | -> Seq Scan on users u (rows=4000) |
| | 150 | -> Seq Scan on semesters_subjects ss (rows=80000) (actual time=0.032..5.444) |
| | 151 | -> Seq Scan on passed_subjects ps_1 (rows=56000) (actual time=0.042..6.293) |
| | 152 | -> Seq Scan on payment p (rows=16000) (actual time=0.028..0.794) |
| | 153 | -> Seq Scan on user_documents ud (rows=4000) |
| | 154 | Execution Time: 188.547 ms |
| | 155 | }}} |
| | 156 | |
| | 157 | '''План ПО индексите''' ([attachment:after_rep_student_dossier.txt]): |
| | 158 | |
| | 159 | {{{ |
| | 160 | -> Seq Scan on users u (rows=4000) |
| | 161 | -> Seq Scan on semesters_subjects ss (rows=80000) (actual time=0.013..4.720) |
| | 162 | -> Seq Scan on passed_subjects ps_1 (rows=56000) (actual time=0.012..5.112) |
| | 163 | -> Seq Scan on payment p (rows=16000) (actual time=0.028..0.788) |
| | 164 | -> Seq Scan on user_documents ud (rows=4000) |
| | 165 | Execution Time: 179.370 ms |
| | 166 | }}} |
| | 167 | |
| | 168 | '''Заклучок:''' идентичен план. Извештајот бара досие за сите 4.000 студенти, па |
| | 169 | {{{ix_payment_enrollment}}} не помага — сите 16.000 плаќања и онака се потребни. |
| | 170 | Спореди со Прашалник 6, каде истата рутина го користи тој индекс. |
| | 171 | |
| | 172 | === Прашалник 3 - најуспешен студент по програма (Фаза 6, Извештај 3) |
| | 173 | |
| | 174 | {{{#!sql |
| | 175 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM rep_top_student_per_major(); |
| | 176 | }}} |
| | 177 | |
| | 178 | '''План ПРЕД''' ([attachment:before_rep_top_student_per_major.txt]) и |
| | 179 | '''ПО''' ([attachment:after_rep_top_student_per_major.txt]) — идентични јазли: |
| | 180 | |
| | 181 | {{{ |
| | 182 | -> Seq Scan on semesters_subjects ss (rows=80000) |
| | 183 | -> Seq Scan on passed_subjects ps (rows=56000) |
| | 184 | -> Seq Scan on enrolled_semesters es (rows=16000) |
| | 185 | -> Index Scan using users_pkey on users u (loops=6) |
| | 186 | |
| | 187 | Пред: Execution Time: 107.303 ms |
| | 188 | По: Execution Time: 93.983 ms |
| | 189 | }}} |
| | 190 | |
| | 191 | '''Заклучок:''' единствениот Index Scan е по {{{users_pkey}}}, кој постоеше и пред |
| | 192 | измената. Ниту еден нов индекс не е употребен. |
| | 193 | |
| | 194 | === Прашалник 4 - најоптоварен професор (Фаза 6, Извештај 4) |
| | 195 | |
| | 196 | {{{#!sql |
| | 197 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM rep_busiest_professor(); |
| | 198 | }}} |
| | 199 | |
| | 200 | '''План ПРЕД''' ([attachment:before_rep_busiest_professor.txt]) и |
| | 201 | '''ПО''' ([attachment:after_rep_busiest_professor.txt]): |
| | 202 | |
| | 203 | {{{ |
| | 204 | -> Seq Scan on semesters_subjects ss (rows=80000) <- исто пред и по |
| | 205 | -> Seq Scan on passed_subjects ps (rows=56000) |
| | 206 | -> Seq Scan on enrolled_semesters es (rows=16000) |
| | 207 | |
| | 208 | Пред: Execution Time: 121.914 ms |
| | 209 | По: Execution Time: 124.648 ms |
| | 210 | }}} |
| | 211 | |
| | 212 | '''Заклучок:''' иако постои {{{ix_semesters_subjects_professor}}}, планерот не го |
| | 213 | зема, бидејќи извештајот групира по '''сите''' професори, не бара еден. Истиот |
| | 214 | индекс е одлучувачки кај Прашалник 7, каде има услов за еден професор. |
| | 215 | |
| | 216 | === Прашалник 5 - промена на активноста (Фаза 6, Извештај 5) |
| | 217 | |
| | 218 | {{{#!sql |
| | 219 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM rep_semester_growth(); |
| | 220 | }}} |
| | 221 | |
| | 222 | '''План ПРЕД''' ([attachment:before_rep_semester_growth.txt]) и |
| | 223 | '''ПО''' ([attachment:after_rep_semester_growth.txt]): |
| | 224 | |
| | 225 | {{{ |
| | 226 | -> Seq Scan on semesters_subjects ss (rows=80000) <- исто пред и по |
| | 227 | -> Seq Scan on passed_subjects ps (rows=56000) |
| | 228 | -> Seq Scan on enrolled_semesters es (rows=16000) |
| | 229 | -> Seq Scan on active_semesters a (rows=20) |
| | 230 | |
| | 231 | Пред: Execution Time: 124.040 ms |
| | 232 | По: Execution Time: 138.077 ms |
| | 233 | }}} |
| | 234 | |
| | 235 | '''Заклучок:''' {{{ix_enrolled_semesters_semester}}} не е употребен, иако извештајот |
| | 236 | групира по semester_id — пак затоа што ги чита сите 20 семестри. |
| | 237 | |
| | 238 | === Прашалник 6 - досие на еден студент (Фаза 6, Извештај 2 со аргумент) |
| | 239 | |
| | 240 | {{{#!sql |
| | 241 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM rep_student_dossier(2500); |
| | 242 | }}} |
| | 243 | |
| | 244 | '''План ПРЕД индексот''' ([attachment:before_dossier_one.txt]) — целата табела |
| | 245 | payment се чита: |
| | 246 | |
| | 247 | {{{ |
| | 248 | -> Seq Scan on payment p (cost=0.00..247.00 rows=16000 width=8) |
| | 249 | (actual time=0.011..0.624 rows=16000.00 loops=1) |
| | 250 | Execution Time: 2.190 ms |
| | 251 | }}} |
| | 252 | |
| | 253 | '''План ПО индексот''' ([attachment:after_dossier_one.txt]) — истата табела се чита |
| | 254 | преку индекс: |
| | 255 | |
| | 256 | {{{ |
| | 257 | -> Index Scan using ix_payment_enrollment on payment p |
| | 258 | (cost=0.29..8.30 rows=1 width=8) |
| | 259 | (actual time=0.090..0.090 rows=1.00 loops=4) |
| | 260 | Index Cond: (enrollment_id = es_3.id) |
| | 261 | Execution Time: 1.067 ms |
| | 262 | }}} |
| | 263 | |
| | 264 | '''Заклучок:''' индексот {{{ix_payment_enrollment}}} е '''докажано употребен''' — |
| | 265 | неговото име стои во јазлот. Наместо 16.000 реда се читаат 4 (по еден за секој |
| | 266 | семестар на студентот), а времето паѓа од 2,19 на 1,07 ms. |
| | 267 | |
| | 268 | Ова е најважната споредба во целата анализа: Прашалници 2 и 6 се '''истата |
| | 269 | рутина од Фаза 6'''. Разликата е само во аргументот, а тоа е доволно планот да се |
| | 270 | промени од Seq Scan во Index Scan. |
| | 271 | |
| | 272 | === Прашалник 7 - дневник на професор (барање на апликацијата) |
| | 273 | |
| | 274 | {{{#!sql |
| | 275 | SELECT u.surname, u.name, s.name AS subject, ss.signature, ps.grade |
| | 276 | FROM semesters_subjects ss |
| | 277 | JOIN enrolled_semesters es ON es.id = ss.enrolled_semesters_id |
| | 278 | JOIN users u ON u.id = es.user_id |
| | 279 | JOIN subjects s ON s.id = ss.subjects_id |
| | 280 | LEFT JOIN passed_subjects ps ON ps.enrolled_id = ss.id |
| | 281 | WHERE ss.professor_id = 47 |
| | 282 | ORDER BY s.name, u.surname; |
| | 283 | }}} |
| | 284 | |
| | 285 | '''План ПРЕД индексот''' ([attachment:before_gradebook.txt]): |
| | 286 | |
| | 287 | {{{ |
| | 288 | -> Seq Scan on semesters_subjects ss (cost=0.00..1510.00 rows=664 width=13) |
| | 289 | (actual time=0.038..6.061 rows=684.00 loops=1) |
| | 290 | Filter: (professor_id = 47) |
| | 291 | Rows Removed by Filter: 79316 |
| | 292 | Execution Time: 16.332 ms |
| | 293 | }}} |
| | 294 | |
| | 295 | '''План ПО индексот''' ([attachment:after_gradebook.txt]): |
| | 296 | |
| | 297 | {{{ |
| | 298 | -> Bitmap Heap Scan on semesters_subjects ss (cost=9.45..555.06 rows=666 width=13) |
| | 299 | (actual time=0.108..1.480 rows=684.00 loops=1) |
| | 300 | Recheck Cond: (professor_id = 47) |
| | 301 | -> Bitmap Index Scan on ix_semesters_subjects_professor |
| | 302 | (cost=0.00..9.29 rows=666 width=0) |
| | 303 | (actual time=0.070..0.070 rows=684.00 loops=1) |
| | 304 | Index Cond: (professor_id = 47) |
| | 305 | Execution Time: 7.615 ms |
| | 306 | }}} |
| | 307 | |
| | 308 | '''Заклучок:''' индексот {{{ix_semesters_subjects_professor}}} е '''докажано |
| | 309 | употребен'''. Пред индексот базата читаше 80.000 реда и отфрлаше 79.316 |
| | 310 | ({{{Rows Removed by Filter}}}); по индексот оди директно до 684-те реда. Цената |
| | 311 | паѓа од 1510 на 555, а времето од 16,3 на 7,6 ms. |
| | 312 | |
| | 313 | === Зошто петте агрегатни извештаи не станаа побрзи |
| | 314 | |
| | 315 | Ова не е неуспех на индексите, туку очекувано однесување. Прашалници 1-5 се |
| | 316 | агрегатни - тие читаат '''сѐ''' од semesters_subjects, passed_subjects и |