Changes between Version 2 and Version 3 of OtherTopics


Ignore:
Timestamp:
09/24/26 20:30:42 (4 days ago)
Author:
233149
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • OtherTopics

    v2 v3  
    6565ограничување.
    6666
    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
     115EXPLAIN (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)
     124Execution 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)
     133Execution Time: 156.015 ms
     134}}}
     135
     136'''Заклучок:''' планот е идентичен — во него '''не се појавува ниту еден''' од
     137новите индекси. Барањето агрегира врз целите табели, па планерот точно
     138заклучува дека секвенцијалното читање е поевтино.
     139
     140=== Прашалник 2 - досие на сите студенти (Фаза 6, Извештај 2)
     141
     142{{{#!sql
     143EXPLAIN (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)
     154Execution 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)
     165Execution 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
     175EXPLAIN (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
     197EXPLAIN (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
     219EXPLAIN (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
     241EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM rep_student_dossier(2500);
     242}}}
     243
     244'''План ПРЕД индексот''' ([attachment:before_dossier_one.txt]) — целата табела
     245payment се чита:
     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)
     250Execution 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)
     261Execution 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
     275SELECT u.surname, u.name, s.name AS subject, ss.signature, ps.grade
     276FROM semesters_subjects ss
     277JOIN enrolled_semesters es ON es.id = ss.enrolled_semesters_id
     278JOIN users u              ON u.id  = es.user_id
     279JOIN subjects s           ON s.id  = ss.subjects_id
     280LEFT JOIN passed_subjects ps ON ps.enrolled_id = ss.id
     281WHERE ss.professor_id = 47
     282ORDER 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
     292Execution 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)
     305Execution 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 и
    82317enrolled_semesters, за да пресметаат проодност, просек или ранг. Кога барањето и
    83318онака мора да ги прочита сите редови, секвенцијалното читање е побрзо од
    … …  
    85320скока по индексот и потоа по табелата.
    86321
    87 Дека разликите во табелата се шум, а не забавување, се гледа од повторените
     322Дека разликите во времињата се шум, а не забавување, се гледа од повторените
    88323мерења на истото барање со исти индекси:
    89324
    … …  
    96331
    97332Распонот од околу 28 ms меѓу четири последователни извршувања е поголем од сите
    98 разлики „пред/по“ во табелата. Значи индексите за овие барања не менуваат ништо -
    99 ниту на добро, ниту на лошо.
    100 
    101 === Каде индексите навистина помогнаа
    102 
    103 Кај двете '''селективни''' барања - оние кои бараат податоци за еден студент или
    104 за еден професор - разликата е јасна и се гледа во самиот план.
    105 
    106 '''Досие на еден студент''' (2,19 ms → 1,07 ms). Планот пред индексите содржеше:
    107 
    108 {{{
    109 Seq Scan on payment
    110 }}}
    111 
    112 а по индексите:
    113 
    114 {{{
    115 Index Scan using ix_payment_enrollment
    116 }}}
    117 
    118 '''Дневник на професор''' (16,3 ms → 7,6 ms). Пред индексот:
    119 
    120 {{{
    121 Seq Scan on semesters_subjects   (80.000 реда прочитани, филтрирани на ~660)
    122 }}}
    123 
    124 По индексот:
    125 
    126 {{{
    127 Bitmap Heap Scan on semesters_subjects
    128   -> Bitmap Index Scan using ix_semesters_subjects_professor
    129 }}}
    130 
    131 Наместо да ги прочита сите 80.000 реда и да ги отфрли 99%, базата сега оди
    132 директно до редовите на тој професор.
     333разлики „пред/по“ во збирната табела. Затоа единствениот сигурен доказ дали
     334индексот се употребува е '''самиот план''', а не измереното време — и токму
     335затоа погоре е даден планот за секој прашалник посебно.
    133336
    134337=== Дали индексите навистина се употребени
    … …  
    260463отворањето е поскапо од вообичаеното.
    261464
    262 
    263465== Историјат
    264466
    … …  
    268470 документирање на безбедносните мерки во апликацијата и во базата.
    269471
     472 '''Верзија 2''' - По забелешки: експлицитно е наведено дека шест од
     473 седумте анализирани прашалници се извештаите од Фаза 6, со име на рутината
     474 во reports.sql за секој. За секој прашалник е документиран планот за
     475 извршување пред и по додавањето на индексите, со извадок од јазлите во
     476 кои се гледа дали индексот се употребува. Додадена е скриптата queries.sql
     477 со точните мерени наредби.
     478
    270479== Статус
    271480