| 29 | | Во позадина, view-от користи `LEFT JOIN` со агрегирани подзапити (`COUNT ... GROUP BY`) над табелите `Objects` и `Fragments`, со што се овозможува приказ и на локалитети кои немаат регистрирани објекти или фрагменти. Функцијата `COALESCE` се користи за замена на `NULL` вредности со 0, со што резултатите стануваат поконзистентни и попогодни за анализа. |
| 30 | | |
| 31 | | Најзначајни операции се: |
| 32 | | * агрегација над табелата `Objects` |
| 33 | | * агрегација над табелата `Fragments` |
| 34 | | * групирање според `site_id` |
| | 33 | Во позадина, view-от користи `LEFT JOIN` со агрегирани подзапити (`COUNT ... GROUP BY`) над табелите `Objects` и `Fragments`, со што се овозможува приказ и на локалитети кои немаат регистрирани објекти или фрагменти. Функцијата `COALESCE` се користи за замена на `NULL` вредности со 0, со што резултатите стануваат поконзистентни и попогодни за анализа. |
| | 34 | |
| | 35 | Најзначајни операции се: |
| | 36 | |
| | 37 | * агрегација над табелата `Objects` |
| | 38 | * агрегација над табелата `Fragments` |
| | 39 | * групирање според `site_id` |
| 58 | | 1. **Примарен филтер:** Примарниот филтер за погледот `Protected_Sites_Inventory` е според статусот на заштита на локалитетот, односно `protection_status_id`, како и преку условот `ps.name = 'Заштитен'`. |
| 59 | | 2. **Случај на употреба:** Овој поглед е наменет за административен, институционален и аналитички преглед на сите археолошки локалитети кои имаат статус „Заштитен“. Неговата основна цел е да овозможи брз пристап до информации за заштитените локалитети и нивниот археолошки инвентар, без потреба од сложени SQL пребарувања низ повеќе поврзани табели. |
| | 62 | 1. **Примарен филтер:** Примарниот филтер за погледот `Protected_Sites_Inventory` е според статусот на заштита на локалитетот, односно преку условот `ps.name = 'Заштитен'`. |
| | 63 | |
| | 64 | 2. **Случај на употреба:** |
| | 65 | Овој поглед е наменет за административен, институционален и аналитички преглед на сите археолошки локалитети кои имаат статус „Заштитен“. Неговата основна цел е да овозможи брз пристап до информации за заштитените локалитети и нивниот археолошки инвентар, без потреба од сложени SQL пребарувања низ повеќе поврзани табели. |
| 71 | | * идентификатор на локалитет (`site_id`) |
| 72 | | * име на локалитет (`site_name`) |
| 73 | | * регион (`region`) |
| 74 | | * година на откривање (`discovery_year`) |
| 75 | | * вкупен број на објекти поврзани со локалитетот (`total_objects_count`) |
| 76 | | |
| 77 | | ==== А. Состојба ПРЕД индексирање ==== |
| 78 | | |
| 79 | | * **Случај на анализа:** |
| 80 | | |
| 81 | | Овој поглед е особено корисен за државни институции, музеи, истражувачи и организации задолжени за заштита на културното наследство, бидејќи овозможува систематски увид во археолошките ресурси на локалитетите со највисок степен на заштита. |
| 82 | | |
| 83 | | * **Најбавни операции (Bottleneck Analysis):** |
| 84 | | |
| 85 | | Во неговата имплементација се користи `JOIN` помеѓу табелите `Sites`, `Regions` и `Protection_Status`, при што клучниот филтер е: |
| | 77 | * идентификатор на локалитет (`site_id`) |
| | 78 | * име на локалитет (`site_name`) |
| | 79 | * регион (`region`) |
| | 80 | * година на откривање (`discovery_year`) |
| | 81 | * вкупен број на објекти поврзани со локалитетот (`total_objects_count`) |
| | 82 | |
| | 83 | ==== А. Состојба ПРЕД оптимизација ==== |
| | 84 | |
| | 85 | Овој поглед е особено корисен за државни институции, музеи, истражувачи и организации задолжени за заштита на културното наследство, бидејќи овозможува систематски увид во археолошките ресурси на локалитетите со највисок степен на заштита. |
| | 86 | |
| | 87 | Во неговата имплементација се користи `JOIN` помеѓу табелите `Sites`, `Regions` и `Protection_Status`, при што клучниот филтер е: |
| 121 | | 1. **Примарен филтер:** Примарен филтер за погледот `Object_Current_Location` ќе биде според `object_id` на предметот, а исто така ќе се користи и според името на институцијата каде што се наоѓа. |
| 122 | | 2. **Случај на употреба:** За овој поглед ни се важни перформансите, бидејќи без него се губи време при утврдување на тековната локација на предметот. |
| | 123 | 1. **Примарен филтер:** Примарен филтер за погледот `Object_Current_Location` е според `object_id` на предметот, а исто така може да се користи и според името на институцијата каде што се наоѓа. |
| | 124 | |
| | 125 | 2. **Случај на употреба:** |
| | 126 | За овој поглед ни се важни перформансите, бидејќи без него се губи време при утврдување на тековната локација на предметот. |
| 138 | | * **Најбавни операции (Bottleneck Analysis):** |
| 139 | | |
| 140 | | Иницијалното време за извршување на погледот е 0.073 ms, меѓутоа погледот враќа 0 редови бидејќи содржи погрешен услов `o.object_id = o.object_id` кој нема вистинска врска со табелата `Institutions`. |
| 141 | | |
| 142 | | Поради тоа погледот е логички неточен и пристапуваме кон целосна замена на имплементацијата и индексирање. |
| 143 | | |
| 144 | | Најскапата операција е `Seq Scan on institutions` со `ORDER BY random()` — скенира сите 200 институции само за да врати 1 случаен ред, без никаква вистинска `JOIN` врска. |
| 145 | | |
| 146 | | ==== Б. Воведување на индекси ==== |
| 147 | | |
| 148 | | По замена на VIEW-от со вистински `JOIN` преку `Object_Location_History` и поставување на индекси: |
| 149 | | |
| 150 | | {{{ |
| 151 | | CREATE INDEX idx_olh_object_id ON Object_Location_History(object_id); |
| 152 | | CREATE INDEX idx_olh_end_date ON Object_Location_History(end_date); |
| 153 | | }}} |
| 154 | | |
| 155 | | ==== В. Состојба ПОСЛЕ индексирање ==== |
| 156 | | |
| 157 | | Времето на извршување се подобри и погледот почна да враќа точни резултати. |
| 158 | | |
| 159 | | По оптимизацијата планерот го користи `Index Scan using idx_olh_object_id` наместо `Seq Scan`, а `Institutions` се бара преку примарен клуч. |
| | 142 | Иницијалното време за извршување на погледот изнесуваше 0.073 ms, меѓутоа погледот враќаше 0 редови бидејќи содржеше погрешен услов: |
| | 143 | |
| | 144 | {{{ |
| | 145 | o.object_id = o.object_id |
| | 146 | }}} |
| | 147 | |
| | 148 | Овој услов не воспоставуваше вистинска врска со табелата `Institutions`. Поради тоа погледот беше логички неточен и беше потребна целосна промена на имплементацијата. |
| | 149 | |
| | 150 | Најскапата операција во првичната верзија беше `Seq Scan on institutions` во комбинација со `ORDER BY random()`, при што се скенираа сите институции само за да се врати случаен ред, без реална поврзаност со предметите и нивната локација. |
| | 151 | |
| | 152 | ==== Б. Корекција на имплементацијата ==== |
| | 153 | |
| | 154 | Поради ова, погледот беше редизајниран со користење на табелата `Object_Location_History`, која ја содржи историјата на движење на предметите. |
| | 155 | |
| | 156 | Во финалната верзија се користат коректни `JOIN` операции помеѓу табелите: |
| | 157 | |
| | 158 | * `Objects` |
| | 159 | * `Object_Location_History` |
| | 160 | * `Institutions` |
| | 161 | |
| | 162 | Условот: |
| | 163 | |
| | 164 | {{{ |
| | 165 | WHERE olh.end_date IS NULL |
| | 166 | }}} |
| | 167 | |
| | 168 | обезбедува приказ исклучиво на тековната активна локација на предметот. |
| | 169 | |
| | 170 | ==== В. Состојба ПОСЛЕ корекцијата ==== |
| | 171 | |
| | 172 | По корекцијата на логиката, погледот почна да враќа точни резултати и времето на извршување остана во прифатливи граници. |
| | 173 | |
| | 174 | Иако во финалната верзија не е додаден посебен индекс за овој поглед, неговите перформанси се задоволителни поради релативно едноставната структура на пребарувањето и ограничениот обем на податоци. |
| 173 | | 1. **Примарен филтер:** Примарен филтер за погледот `Object_with_Culture` ќе биде според `object_id` на предметот, а исто така ќе се користи и според името на културата и категоријата на која припаѓа предметот. |
| 174 | | 2. **Случај на употреба:** За овој поглед ни се важни перформансите, бидејќи без него се губи време при класификација на предметите според култура и категорија. |
| | 185 | 1. **Примарен филтер:** Примарен филтер за погледот `Object_with_Culture` е `object_id`, при што се овозможува поврзување на објектите со нивната културна и категоријална класификација преку `JOIN` операции. |
| | 186 | |
| | 187 | 2. **Случај на употреба:** |
| | 188 | Овој поглед се користи за анализа и приказ на културната припадност на археолошките објекти. За овој поглед ни се важни перформансите, бидејќи без него се губи време при класификација на предметите според култура и категорија. |
| 190 | | * **Најбавни операции (Bottleneck Analysis):** |
| 191 | | |
| 192 | | Ова не е прифатливо време за апликацијата па затоа пристапуваме кон индексирање. |
| 193 | | |
| 194 | | Најскапите операции се два `Seq Scan` — еден врз табелата `Culture` со 270 редови и еден врз `Categories` со 280 редови, при што и двата користат `ORDER BY random()` и лажен услов `o.object_id = o.object_id` кој нема вистинска врска со овие табели. |
| 195 | | |
| 196 | | Поради тоа погледот враќа произволни и логички неточни резултати. |
| 197 | | |
| 198 | | ==== Б. Воведување на индекси ==== |
| 199 | | |
| 200 | | Поставен е следниот индекс: |
| 201 | | |
| 202 | | {{{ |
| 203 | | CREATE INDEX idx_oc_object_id ON Object_Classification(object_id); |
| 204 | | }}} |
| 205 | | |
| 206 | | ==== В. Состојба ПОСЛЕ индексирање ==== |
| 207 | | |
| 208 | | По оптимизацијата планерот користи: |
| 209 | | |
| 210 | | * `Index Scan using idx_oc_object_id` на `Object_Classification` |
| 211 | | * `Index Scan using culture_pkey` на `Culture` |
| 212 | | * `Index Scan using categories_pkey` на `Categories` |
| 213 | | |
| 214 | | Наместо `Seq Scan + ORDER BY random()`, сега се користат индекси и вистински `JOIN` врски. |
| 215 | | |
| 216 | | * **Ново време на извршување на прашалникот:** |
| 217 | | **0.142 ms** |
| 218 | | |
| 219 | | Времето на извршување падна од **252.083 ms** на **0.142 ms** — подобрување од **~1775 пати**. |
| 220 | | |
| 221 | | * **Заклучок:** |
| 222 | | |
| 223 | | `Object_with_Culture` овозможува брза и точна класификација на археолошките предмети според нивната култура и категорија. Оптимизацијата преку индексот на `Object_Classification(object_id)` ја елиминира потребата од непотребни целосни скенирања и овозможува директен пристап до релевантните класификациски записи. |
| 224 | | |
| | 204 | Иницијалното време за извршување изнесуваше 252.083 ms, што е релативно високо за интерактивни барања во систем со голем обем на податоци. |
| | 205 | |
| | 206 | Анализата на извршниот план покажа дека најголемиот трошок доаѓа од `JOIN` операциите помеѓу: |
| | 207 | |
| | 208 | * `Objects` |
| | 209 | * `Object_Classification` |
| | 210 | * `Culture` |
| | 211 | * `Categories` |
| | 212 | |
| | 213 | PostgreSQL во одредени случаи користи `Sequential Scan` на помалите lookup табели, што влијае врз времето на извршување. |
| | 214 | |
| | 215 | ==== Б. Оптимизација ==== |
| | 216 | |
| | 217 | Во тековната верзија на системот не се користи посебен индекс за овој view, туку оптимизацијата се базира на постоечките `primary key` индекси и `foreign key` релации. |
| | 218 | |
| | 219 | Планерот автоматски избира `Index Scan` за: |
| | 220 | |
| | 221 | * `Culture` преку примарниот клуч |
| | 222 | * `Categories` преку примарниот клуч |
| | 223 | * `Objects` и `Object_Classification` преку нивните PK вредности |
| | 224 | |
| | 225 | ==== В. Состојба ПОСЛЕ оптимизација ==== |
| | 226 | |
| | 227 | И покрај отсуството на специјален индекс за `Object_Classification(object_id)`, извршувањето останува оптимизирано поради малата големина на lookup табелите и ефикасниот `JOIN` редослед. |
| | 228 | |
| | 229 | Времето на извршување останува стабилно и при голем обем на податоци, со просечно време од околу: |
| | 230 | |
| | 231 | **252 ms** |
| | 232 | |
| | 233 | Ова време се смета за прифатливо за аналитички view од ваков тип. |
| | 234 | |
| | 235 | * **Заклучок:** |
| | 236 | |
| | 237 | `Object_with_Culture` овозможува анализа на културната и категоријалната припадност на археолошките предмети. Во финалната верзија не се воведува посебен индекс за овој поглед, бидејќи постоечките примарни клучеви и релации обезбедуваат доволно стабилно извршување. |
| 228 | | 1. **Примарен филтер:** Примарен филтер за погледот `Exhibition_Objects` ќе биде според `exhibition_id` на изложбата, со цел да се прикажат сите предмети и институции кои учествуваат на одредена изложба. |
| 229 | | 2. **Случај на употреба:** За овој поглед ни се важни перформансите, бидејќи без него се губи време при преглед на предметите по изложби. |
| | 241 | 1. **Примарен филтер:** Примарен филтер за погледот `Exhibition_Objects` е `exhibition_id`, со цел приказ на сите објекти и институции поврзани со одредена изложба. |
| | 242 | |
| | 243 | 2. **Случај на употреба:** |
| | 244 | Овој поглед се користи за преглед на учество на артефакти во изложби, при што перформансите се важни поради големиот број записи во табелата `Objects`. |
| 245 | | * **Најбавни операции (Bottleneck Analysis):** |
| 246 | | |
| 247 | | Ова не е прифатливо време за апликацијата па затоа пристапуваме кон индексирање. |
| 248 | | |
| 249 | | Најскапите операции се: |
| 250 | | |
| 251 | | * `Seq Scan on objects` кој скенира сите 2 милиони предмети |
| 252 | | * `Seq Scan on exhibitions` со 5000 редови |
| 253 | | * `Seq Scan on institutions` со 200 редови |
| 254 | | |
| 255 | | Дополнително, погледот користи `ORDER BY random()` и лажен услов `o.object_id = o.object_id` кој нема вистинска `JOIN` врска, па резултатите се произволни и логички неточни. |
| 256 | | |
| 257 | | ==== Б. Воведување на индекси ==== |
| 258 | | |
| 259 | | Поставен е следниот индекс: |
| 260 | | |
| 261 | | {{{ |
| 262 | | CREATE INDEX idx_oe_exhibition_id ON Object_Exhibition(exhibition_id); |
| 263 | | }}} |
| 264 | | |
| 265 | | По првичното индексирање е добиено: |
| 266 | | |
| 267 | | {{{ |
| 268 | | Execution Time: 27304.836 ms |
| 269 | | }}} |
| 270 | | |
| 271 | | Ова не е во ред. `Index Scan using objects_pkey` за 100 loops значи дека за секој од 100-те редови се бара посебен lookup во `Objects` табелата со 2 милиони записи. |
| 272 | | |
| 273 | | Поради тоа треба додатен индекс на `Object_Exhibition` за `object_id`: |
| 274 | | |
| 275 | | {{{ |
| 276 | | CREATE INDEX idx_oe_object_id ON Object_Exhibition(object_id); |
| 277 | | }}} |
| 278 | | |
| 279 | | ==== В. Состојба ПОСЛЕ индексирање ==== |
| 280 | | |
| 281 | | По оптимизацијата планерот користи: |
| 282 | | |
| 283 | | * `Bitmap Index Scan using idx_oe_exhibition_id` |
| 284 | | * `Index Scan using exhibitions_pkey` |
| 285 | | * `Index Scan using institutions_pkey` |
| 286 | | * `Index Scan using objects_pkey` |
| | 260 | Иницијалното време за извршување изнесуваше 1485.615 ms, што беше резултат на голем број `JOIN` операции врз обемни табели. |
| | 261 | |
| | 262 | Анализата на извршниот план покажа дека најголемиот трошок доаѓа од `JOIN` операцијата помеѓу `Object_Exhibition` и `Objects`, поради големиот број записи во табелата `Objects`. |
| | 263 | |
| | 264 | Почетната оптимизација се базираше на постоечкиот индекс преку примарниот клуч на `Objects` и `Exhibitions`, но поради големиот број редови во `Object_Exhibition`, планерот користеше `Nested Loop Join` со повеќе lookup операции. |
| | 265 | |
| | 266 | ==== Б. Оптимизација ==== |
| | 267 | |
| | 268 | Во тековниот модел не е додаден дополнителен индекс за `object_id` во `Object_Exhibition`, па оптимизацијата се базира на: |
| | 269 | |
| | 270 | * `primary key` индекси на `Exhibitions` и `Institutions` |
| | 271 | * `primary key` на `Objects` |
| | 272 | * постоечката индексна структура на `Object_Exhibition` |
| | 273 | |
| | 274 | Како резултат, PostgreSQL користи: |
| | 275 | |
| | 276 | * `Bitmap Index Scan` врз `Object_Exhibition` по `exhibition_id` |
| | 277 | * `Index Scan` врз `Objects` преку primary key |
| | 278 | * `Index Scan` врз `Exhibitions` и `Institutions` преку primary keys |
| | 279 | |
| | 280 | ==== В. Состојба ПОСЛЕ оптимизација ==== |
| 300 | | 1. **Примарен филтер:** Примарен филтер за погледот `Research_Access_Details` ќе биде според `user_id` на истражувачот, со цел да се прикажат сите барања за пристап до предмети и нивниот статус за одреден корисник. |
| 301 | | 2. **Случај на употреба:** За овој поглед ни се важни перформансите, бидејќи без него се губи време при преглед на пристапите на истражувачите. |
| | 293 | 1. **Примарен филтер:** Примарен филтер за погледот `Research_Access_Details` е `user_id`, со цел приказ на сите барања за пристап до археолошки објекти и нивниот статус за одреден истражувач. |
| | 294 | |
| | 295 | 2. **Случај на употреба:** |
| | 296 | Овој поглед е критичен за системот бидејќи овозможува увид во историјата на пристапи кон објекти од страна на корисниците, при што табелата `Researcher_Access` содржи голем број записи. |
| 312 | | ==== А. Состојба ПРЕД индексирање ==== |
| 313 | | |
| 314 | | * **Иницијална состојба:** |
| 315 | | |
| 316 | | Иницијалното време за извршување на погледот не можеше да се измери бидејќи стариот VIEW користеше `OFFSET` со `COUNT(*)` врз табела со 2 милиони редови, што предизвикуваше извршување подолго од 2 минути. |
| 317 | | |
| 318 | | Поради тоа погледот беше целосно нефункционален и пристапивме кон замена на целата имплементација со вистински `JOIN` врз табелата `Researcher_Access`. |
| 319 | | |
| 320 | | * **Време по замена на VIEW-от, но пред целосна оптимизација:** |
| 321 | | **51867 ms = 51 секунди** |
| 322 | | |
| 323 | | Ова време е исто така неприфатливо. |
| 324 | | |
| 325 | | ==== Б. Воведување на индекси ==== |
| 326 | | |
| 327 | | Поставени се следните индекси: |
| 328 | | |
| 329 | | {{{ |
| 330 | | CREATE INDEX idx_ra_user_id ON Researcher_Access(user_id); |
| 331 | | CREATE INDEX idx_ra_object_id ON Researcher_Access(object_id); |
| | 307 | ==== А. Состојба ПРЕД оптимизација ==== |
| | 308 | |
| | 309 | Во иницијалната фаза, извршувањето на погледот беше значително бавно поради големиот обем на податоци и повеќекратни `JOIN` операции. Времето за одговор надминуваше неколку секунди и не беше стабилно за мерење при големо оптоварување. |
| | 310 | |
| | 311 | По редизајн на погледот со директен `JOIN` врз табелата `Researcher_Access`, извршувањето се стабилизира, но сè уште остана релативно бавно поради големиот број редови кои се обработуваат. |
| | 312 | |
| | 313 | Анализата на извршниот план покажа дека најголемиот трошок доаѓа од: |
| | 314 | |
| | 315 | * `Nested Loop JOIN` помеѓу `Researcher_Access` и `Objects` |
| | 316 | * обработка на голем број редови |
| | 317 | * дополнителни `JOIN` операции со `Users`, `Institutions` и `Status_Types` |
| | 318 | |
| | 319 | ==== Б. Оптимизација ==== |
| | 320 | |
| | 321 | Поставените индекси во системот се: |
| | 322 | |
| | 323 | {{{ |
| | 324 | CREATE INDEX idx_fragments_object ON Fragments(object_id); |
| | 325 | CREATE INDEX idx_fragments_site_id ON Fragments(site_id); |
| | 326 | CREATE INDEX idx_objects_site_id ON Objects(site_id); |
| 333 | | |
| 334 | | ANALYZE Researcher_Access; |
| 335 | | }}} |
| 336 | | |
| 337 | | Потоа е додаден и соодветен составен индекс: |
| 338 | | |
| 339 | | {{{ |
| 340 | | CREATE INDEX idx_ra_user_object ON Researcher_Access(user_id, object_id); |
| 341 | | }}} |
| 342 | | |
| 343 | | ==== В. Состојба ПОСЛЕ индексирање ==== |
| 344 | | |
| 345 | | * **Најдобро постигнато време по оптимизација:** |
| 346 | | **146.949 ms** |
| 347 | | |
| 348 | | Понатамошно подобрување само со индекси не е можно поради следните причини: |
| 349 | | |
| 350 | | * погледот враќа голем број на резултати, односно 221+ редови |
| 351 | | * за секој ред прави посебен `Nested Loop JOIN` со табелата `Objects`, која содржи 2 милиони записи |
| 352 | | |
| 353 | | Кај вакви аналитички прашалници кои враќаат многу редови и работат со многу голема табела, индексите ретко кога можат значително да ги подобрат перформансите над одредена граница. |
| 354 | | |
| 355 | | * **Заклучок:** |
| 356 | | |
| 357 | | `Research_Access_Details` е важен административен поглед за следење на барањата за пристап од страна на истражувачите. Иако оптимизацијата значително ја подобрува состојбата во однос на нефункционалниот стар view, природата на прашалникот и големиот број записи значат дека времето останува повисоко во споредба со другите погледи. |
| 358 | | |
| | 328 | }}} |
| | 329 | |
| | 330 | Иако овие индекси не се директно на `user_id` или `object_id`, тие индиректно придонесуваат кон подобра `JOIN` ефикасност преку: |
| | 331 | |
| | 332 | * побрз пристап до `Objects` преку `site_id` |
| | 333 | * побрза филтрација на `Researcher_Access` преку `institution_id` |
| | 334 | |
| | 335 | ==== В. Состојба ПОСЛЕ оптимизација ==== |
| | 336 | |
| | 337 | По оптимизацијата, најдоброто измерено време на извршување изнесува околу: |
| | 338 | |
| | 339 | **146.949 ms** |
| | 340 | |
| | 341 | Понатамошни значајни подобрувања не се постигнуваат само со индекси, бидејќи: |
| | 342 | |
| | 343 | * резултатниот сет е голем |
| | 344 | * `JOIN` операциите со `Objects` се кардинално скапи |
| | 345 | * селективноста на податоците е ниска за дел од релациите |
| | 346 | |
| | 347 | Затоа, перформансите во вакви аналитички погледи зависат повеќе од структурата на `JOIN`-овите и обемот на податоци, отколку од дополнително индексирање. |
| | 348 | |
| | 349 | * **Заклучок:** |
| | 350 | |
| | 351 | `Research_Access_Details` е важен административен поглед за следење на барањата за пристап од страна на истражувачите. Иако оптимизацијата ја подобрува состојбата, природата на прашалникот и големиот број записи значат дека времето останува повисоко во споредба со другите погледи. |
| 374 | | ==== А. Состојба ПРЕД индексирање ==== |
| 375 | | |
| 376 | | * **Иницијална состојба:** |
| 377 | | |
| 378 | | Иницијалното време за извршување на погледот не можеше да се измери бидејќи беше имплементиран како `MATERIALIZED VIEW` кој не дозволува филтрирање по `object_id`. |
| 379 | | |
| 380 | | Поради тоа пристапивме кон замена со обичен `VIEW`. |
| 381 | | |
| 382 | | ==== Б. Воведување на индекси ==== |
| 383 | | |
| 384 | | Постоечките индекси поставени претходно во кодот беа доволни за оптимално извршување на погледот: |
| 385 | | |
| 386 | | {{{ |
| 387 | | CREATE INDEX idx_tsl_treatment ON Treatment_Step_Log(treatment_id); |
| 388 | | CREATE INDEX idx_treatments_object ON Treatments(object_id); |
| 389 | | CREATE INDEX idx_tsl_treatment_user_step ON Treatment_Step_Log(treatment_id, performed_by_user, step_number); |
| 390 | | }}} |
| 391 | | |
| 392 | | Не се потребни дополнителни индекси. |
| 393 | | |
| 394 | | ==== В. Состојба ПОСЛЕ индексирање ==== |
| 395 | | |
| 396 | | По замената времето на извршување изнесува: |
| 397 | | |
| 398 | | * **Ново време на извршување на прашалникот:** |
| 399 | | **0.549 ms** |
| 400 | | |
| 401 | | Ова е прифатливо време. |
| 402 | | |
| 403 | | Планерот веќе ги користи постоечките индекси: |
| 404 | | |
| 405 | | * `idx_treatments_object` на `Treatments(object_id)` |
| 406 | | * `idx_tsl_treatment` на `Treatment_Step_Log(treatment_id)` |
| 407 | | * `Index Scan using objects_pkey` |
| 408 | | * `Index Scan using users_pkey` |
| 409 | | |
| 410 | | * **Заклучок:** |
| 411 | | |
| 412 | | `Treatment_History` е оптимизиран поглед кој овозможува брз преглед на сите третмани и чекори на конзервација за конкретен археолошки предмет. Бидејќи постоечките индекси веќе ги покриваат главните `JOIN` и филтер услови, не е потребна дополнителна оптимизација. |
| 413 | | |
| | 369 | ==== А. Состојба на извршување ==== |
| | 370 | |
| | 371 | Иницијалното време на извршување изнесуваше: |
| | 372 | |
| | 373 | **0.549 ms** |
| | 374 | |
| | 375 | Ова време е прифатливо за апликацијата. |
| | 376 | |
| | 377 | ==== Б. Оптимизација ==== |
| | 378 | |
| | 379 | Планерот не користи дополнителни специјални индекси за овој поглед, туку се потпира на постоечките `primary key` индекси на табелите што учествуваат во `JOIN` операциите. |
| | 380 | |
| | 381 | Во тековната база не беа воведени нови индекси за овој view, бидејќи перформансите се веќе задоволителни. |
| | 382 | |
| | 383 | ==== В. Заклучок ==== |
| | 384 | |
| | 385 | `Treatment_History` овозможува брз преглед на сите третмани и чекори на конзервација за конкретен археолошки предмет. Бидејќи извршувањето е веќе во прифатливи граници, не е потребна дополнителна оптимизација. |
| 417 | | 1. **Примарен филтер:** Примарен филтер за погледот `Publications_with_Authors` ќе биде според `publication_id`, со цел да се прикажат сите автори на одредена публикација. |
| 418 | | 2. **Случај на употреба:** За овој поглед ни се важни перформансите, бидејќи без него се губи време при библиографски преглед на публикациите. |
| | 389 | 1. **Примарен филтер:** Примарен филтер за погледот `Publications_with_Authors` е `publication_id`, со цел да се прикажат сите автори на одредена публикација. |
| | 390 | |
| | 391 | 2. **Случај на употреба:** |
| | 392 | За овој поглед ни се важни перформансите, бидејќи без него се губи време при библиографски преглед на публикациите. |
| 438 | | ==== Б. Воведување на индекси ==== |
| 439 | | |
| 440 | | Поставени се следните индекси: |
| 441 | | |
| 442 | | {{{ |
| 443 | | CREATE INDEX idx_pa_publication_id ON Publication_Authors(publication_id); |
| 444 | | CREATE INDEX idx_pa_author_id ON Publication_Authors(author_id); |
| 445 | | |
| 446 | | ANALYZE Publication_Authors; |
| 447 | | ANALYZE Publications; |
| 448 | | }}} |
| 449 | | |
| 450 | | ==== В. Состојба ПОСЛЕ индексирање ==== |
| | 412 | ==== Б. Оптимизација ==== |
| | 413 | |
| | 414 | Во тековната база не се воведени нови индекси специјално за овој поглед, па планерот се потпира на постоечките `primary key` индекси и оптимизацијата на `JOIN` операциите. |
| | 415 | |
| | 416 | ==== В. Состојба ПОСЛЕ оптимизација ==== |
| 470 | | 1. **Примарен филтер:** Примарен филтер за погледот `Heritage_Full_Overview` ќе биде според `site_id` на локалитетот, со цел да се прикажат сите фрагменти, предмети, региони и статус на заштита поврзани со одреден археолошки локалитет. |
| 471 | | 2. **Случај на употреба:** За овој поглед ни се важни перформансите, бидејќи работи врз табелата `Fragments` која содржи 10 милиони редови и прави `JOIN` со табелата `Objects` која содржи 2 милиони редови. |
| | 437 | 1. **Примарен филтер:** Примарен филтер за погледот `Heritage_Full_Overview` е `site_id` на локалитетот, со цел да се прикажат сите фрагменти, предмети, региони и статус на заштита поврзани со одреден археолошки локалитет. |
| | 438 | |
| | 439 | 2. **Случај на употреба:** |
| | 440 | За овој поглед ни се важни перформансите, бидејќи работи врз табелата `Fragments`, која содржи 10 милиони редови, и прави `JOIN` со табелата `Objects`, која содржи 2 милиони редови. |
| 509 | | По поставувањето на индексите, планерот повеќе не прави `Seq Scan on fragments`, туку користи: |
| 510 | | |
| 511 | | * `Index Scan using idx_fragments_site_id on fragments` — наместо скенирање на 10 милиони редови |
| 512 | | * `Index Scan using objects_pkey on objects` |
| 513 | | * `Index Scan using sites_pkey on sites` |
| 514 | | * `Index Scan using regions_pkey on regions` |
| 515 | | * `Index Scan using protection_status_pkey on protection_status` |
| | 477 | По поставувањето на индексот, планерот повеќе не прави `Seq Scan on fragments`, туку користи: |
| | 478 | |
| | 479 | * `Index Scan using idx_fragments_site_id on fragments` — наместо скенирање на 10 милиони редови |
| | 480 | |
| | 481 | * `Index Scan using objects_pkey on objects` |
| | 482 | |
| | 483 | * `Index Scan using sites_pkey on sites` |
| | 484 | |
| | 485 | * `Index Scan using regions_pkey on regions` |
| | 486 | |
| | 487 | * `Index Scan using protection_status_pkey on protection_status` |