| 25 | | * Nested Loop Join со cuisine |
| 26 | | |
| 27 | | Оптимизација: |
| 28 | | {{{ |
| 29 | | CREATE INDEX idx_recipe_cuisine_id ON recipe(cuisine_id); |
| 30 | | }}} |
| 31 | | |
| 32 | | Explain plan (после): |
| 33 | | * Index Scan на recipe |
| | 33 | * Nested Loop Left Join со cuisine |
| | 34 | * Execution Time: ~173 ms |
| | 35 | |
| | 36 | 5. Времето изминато во извршување на операциите insert и update изнесува: |
| | 37 | * INSERT: ~351 ms |
| | 38 | * UPDATE: ~500 ms |
| | 39 | |
| | 40 | 6. Оптимизација: |
| | 41 | Со цел да се забрза спојувањето на табелите и филтрирањето по тип на кујна, се додава индекс на cuisine_id. |
| | 42 | |
| | 43 | {{{ |
| | 44 | CREATE INDEX IF NOT EXISTS idx_recipe_cuisine_id |
| | 45 | ON recipe(cuisine_id); |
| | 46 | }}} |
| | 47 | |
| | 48 | 7. Explain plan (после оптимизација): |
| | 49 | * Bitmap Heap Scan |
| | 50 | * Bitmap Index Scan using idx_recipe_cuisine_id |
| | 51 | * Execution Time: ~19 ms |
| | 52 | |
| | 53 | 8. Времето изминато во извршување на операциите insert и update по индексирање изнесува: |
| | 54 | * INSERT: ~136 ms |
| | 55 | * UPDATE: ~302 ms |
| | 56 | |
| | 57 | 9. Заклучок: |
| | 58 | Со додавање индекс на cuisine_id значително се подобри времето на извршување и пребарувањето по кујна се извршува многу побрзо. |
| | 59 | |
| | 60 | ==== recipe_ingredients_view ==== |
| | 61 | |
| | 62 | 1. Секогаш кога некој ќе отвори рецепт, базата мора да ги повлече сите негови состојки. Ова повлекува JOIN операции помеѓу табелите recipe, ingredient и recipe_ingredient. |
| | 63 | |
| | 64 | 2. Иницијално извршување на погледот. |
| | 65 | |
| | 66 | 3. Explain plan (пред оптимизација): |
| | 67 | * Nested Loop Join |
| | 68 | * Index Scan using recipe_ingredient_pkey |
| | 69 | * Execution Time: ~0.125 ms |
| | 70 | |
| | 71 | 4. Времето изминато во извршување на операциите insert и update изнесува: |
| | 72 | * INSERT: ~112 ms |
| | 73 | * UPDATE: ~131 ms |
| | 74 | |
| | 75 | 5. Оптимизација: |
| | 76 | Овие погледи ги поврзуваат рецептите со нивните состојки. Користењето на индекси на надворешните клучеви во табелата recipe_ingredient ги оптимизира JOIN операциите. |
| | 77 | |
| | 78 | {{{ |
| | 79 | CREATE INDEX IF NOT EXISTS idx_recipe_ingredient_recipe_id |
| | 80 | ON recipe_ingredient(recipe_id); |
| | 81 | |
| | 82 | CREATE INDEX IF NOT EXISTS idx_recipe_ingredient_ingredient_id |
| | 83 | ON recipe_ingredient(ingredient_id); |
| | 84 | }}} |
| | 85 | |
| | 86 | 6. Explain plan (после оптимизација): |
| | 87 | * Nested Loop Join |
| | 88 | * Index Scan using recipe_ingredient_pkey |
| | 89 | * Execution Time: ~0.571 ms |
| | 90 | |
| | 91 | 7. Иако беа креирани дополнителни индекси над колоните recipe_id и ingredient_id, не се забележува значителна промена во execution plan-от. Причината е што базата веќе користи постоечки индекси при извршување на JOIN операциите. |
| | 92 | |
| | 93 | 8. Времето изминато во извршување на операциите insert и update по индексирање изнесува: |
| | 94 | * INSERT: ~210 ms |
| | 95 | * UPDATE: ~85 ms |
| | 96 | |
| | 97 | 9. Заклучок: |
| | 98 | Иако нема значително подобрување во execution plan-от, индексирањето на надворешните клучеви претставува добра практика за оптимизација на JOIN операции кај поголеми табели. |
| | 99 | |
| | 100 | ==== recipe_reviews_view ==== |
| | 101 | |
| | 102 | 1. Примарен филтер: |
| | 103 | Примарен филтер за овој поглед е recipe_id (за прикажување на сите оцени за еден рецепт), а секундарен филтер е user_id (за преглед на сите рецензии оставени од еден корисник). |
| | 104 | |
| | 105 | 2. Случај на употреба: |
| | 106 | Овој поглед е од витално значење за социјалниот аспект на системот. Корисниците се потпираат на оцените и искуствата на другите корисници пред да одлучат да подготват рецепт. Доколку вчитувањето на рецензиите е бавно, корисникот може да ја напушти страницата. |
| | 107 | |
| | 108 | 3. Иницијално извршување на погледот. |
| | 109 | |
| | 110 | 4. Explain plan (пред оптимизација): |
| | 111 | * Nested Loop Join |
| | 112 | * Seq Scan на recipe_review |
| | 113 | * Execution Time: ~484 ms за recipe_id |
| | 114 | * Execution Time: ~0.151 ms за user_id |
| | 115 | |
| | 116 | 5. Времето изминато во извршување на операциите insert и update изнесува: |
| | 117 | * INSERT: ~161 ms |
| | 118 | * UPDATE по recipe_id: ~130 ms |
| | 119 | * UPDATE по recipe_id и user_id: ~149 ms |
| | 120 | |
| | 121 | 6. Оптимизација: |
| | 122 | Со цел да се забрза извршувањето се креираат индекси на recipe_id и user_id. |
| | 123 | |
| | 124 | {{{ |
| | 125 | CREATE INDEX IF NOT EXISTS idx_recipe_review_recipe_id |
| | 126 | ON recipe_review(recipe_id); |
| | 127 | |
| | 128 | CREATE INDEX IF NOT EXISTS idx_recipe_review_user_id |
| | 129 | ON recipe_review(user_id); |
| | 130 | }}} |
| | 131 | |
| | 132 | 7. Explain plan (после оптимизација): |
| | 133 | * Bitmap Heap Scan |
| | 134 | * Bitmap Index Scan using idx_recipe_review_recipe_id |
| | 135 | * Index Scan using recipe_review_user_id_recipe_id_key |
| | 136 | * Execution Time: ~6.487 ms |
| | 137 | |
| | 138 | 8. Времето изминато во извршување на операциите insert и update по индексирање изнесува: |
| | 139 | * INSERT: ~170 ms |
| | 140 | * UPDATE: ~150 ms |
| | 141 | |
| | 142 | 9. Заклучок: |
| | 143 | Со додавање индекси на recipe_id и user_id значително се подобри пребарувањето и вчитувањето на рецензиите. |
| | 144 | |
| | 145 | |
| | 146 | ==== user_favorites_view ==== |
| | 147 | |
| | 148 | 1. Примарен филтер за овој поглед е user_id. |
| | 149 | |
| | 150 | 2. Случај на употреба: |
| | 151 | Корисниците сакаат брзо да ги видат своите омилени рецепти и најчесто зачуваните рецепти во системот. |
| | 152 | |
| | 153 | 3. Иницијално извршување на погледот. |
| | 154 | |
| | 155 | 4. Explain plan (пред оптимизација): |
| | 156 | * Nested Loop Join |
| | 157 | * Seq Scan на recipe_favorite |
| 35 | | |
| 36 | | Заклучок: Значително подобрување, времето е прифатливо. |
| 37 | | |
| 38 | | |
| 39 | | ==== recipe_ingredients_view ==== |
| 40 | | Се користи за прикажување на состојки за даден рецепт, најчесто со филтер по recipe_id. |
| 41 | | |
| 42 | | Време на извршување: |
| 43 | | * Пред оптимизација: 3-8 секунди |
| 44 | | * После оптимизација: 50-200 ms |
| 45 | | |
| 46 | | Explain plan (пред): |
| 47 | | * Seq Scan на recipe_ingredient (10M записи) |
| 48 | | |
| 49 | | Оптимизација: |
| 50 | | {{{ |
| 51 | | CREATE INDEX idx_recipe_ingredient_recipe_id ON recipe_ingredient(recipe_id); |
| 52 | | CREATE INDEX idx_recipe_ingredient_ingredient_id ON recipe_ingredient(ingredient_id); |
| 53 | | }}} |
| 54 | | |
| 55 | | Explain plan (после): |
| 56 | | * Index Scan + Nested Loop |
| 57 | | |
| 58 | | Заклучок: Големо подобрување поради големината на табелата. |
| 59 | | |
| 60 | | |
| 61 | | ==== recipe_reviews_view ==== |
| 62 | | Се користи за приказ на оценки и коментари за рецепти, со филтри по recipe или user. |
| 63 | | |
| 64 | | Време на извршување: |
| 65 | | * Пред оптимизација: 2-5 секунди |
| 66 | | * После оптимизација: 50-150 ms |
| 67 | | |
| 68 | | Оптимизација: |
| 69 | | {{{ |
| 70 | | CREATE INDEX idx_recipe_review_recipe_id ON recipe_review(recipe_id); |
| 71 | | CREATE INDEX idx_recipe_review_user_id ON recipe_review(user_id); |
| 72 | | }}} |
| 73 | | |
| 74 | | Заклучок: Значително намалување на времето. |
| 75 | | |
| 76 | | |
| 77 | | ==== user_favorites_view ==== |
| 78 | | Се користи за прикажување на омилени рецепти за даден корисник. |
| 79 | | |
| 80 | | Време на извршување: |
| 81 | | * Пред оптимизација: 1-3 секунди |
| 82 | | * После оптимизација: 30-100 ms |
| 83 | | |
| 84 | | Оптимизација: |
| 85 | | {{{ |
| 86 | | CREATE INDEX idx_recipe_favorite_user_id ON recipe_favorite(user_id); |
| 87 | | CREATE INDEX idx_recipe_favorite_recipe_id ON recipe_favorite(recipe_id); |
| 88 | | }}} |
| 89 | | |
| 90 | | Заклучок: Прифатливо време по оптимизација. |
| | 159 | * Execution Time: ~97 ms при пребарување по recipe_id |
| | 160 | * Execution Time: ~0.199 ms при пребарување по user_id |
| | 161 | |
| | 162 | Базата користи recipe_favorite_pkey за основни пребарувања по корисник. |
| | 163 | |
| | 164 | 5. Времето изминато во извршување на операциите insert и update изнесува: |
| | 165 | * INSERT: ~170 ms |
| | 166 | * UPDATE: ~224 ms |
| | 167 | |
| | 168 | 6. Оптимизација: |
| | 169 | Со цел да се забрза извршувањето се креираат индекси на recipe_id и user_id. |
| | 170 | |
| | 171 | {{{ |
| | 172 | CREATE INDEX idx_recipe_favorite_user_id |
| | 173 | ON recipe_favorite(user_id); |
| | 174 | |
| | 175 | CREATE INDEX idx_recipe_favorite_recipe_id |
| | 176 | ON recipe_favorite(recipe_id); |
| | 177 | }}} |
| | 178 | |
| | 179 | 7. Explain plan (после оптимизација): |
| | 180 | * Bitmap Heap Scan |
| | 181 | * Bitmap Index Scan using idx_recipe_favorite_recipe_id |
| | 182 | * Index Only Scan using recipe_favorite_pkey |
| | 183 | * Execution Time: ~8.197 ms |
| | 184 | |
| | 185 | 8. Времето изминато во извршување на операциите insert и update по индексирање изнесува: |
| | 186 | * INSERT: ~79 ms |
| | 187 | * UPDATE: ~97 ms |
| | 188 | |
| | 189 | 9. Заклучок: |
| | 190 | Со индексирање на колоните recipe_id и user_id значително се подобри пребарувањето на омилени рецепти и се намали времето на извршување. |
| 94 | | Се користи за прикажување на рецепти со време на подготовка <= 30 минути. |
| 95 | | |
| 96 | | Време на извршување: |
| 97 | | * Пред оптимизација: 500-1000 ms |
| 98 | | * После оптимизација: 20-80 ms |
| 99 | | |
| 100 | | Оптимизација: |
| 101 | | {{{ |
| 102 | | CREATE INDEX idx_recipe_total_time ON recipe(total_time); |
| 103 | | }}} |
| 104 | | |
| 105 | | Заклучок: Филтрирањето значително се подобрува со индекс. |
| | 194 | |
| | 195 | 1. Примарен филтер за овој поглед е total_time. |
| | 196 | |
| | 197 | 2. Случај на употреба: |
| | 198 | Корисниците често пребаруваат "брзи рецепти" кои се готови за под 30 минути. |
| | 199 | |
| | 200 | 3. Проблем: |
| | 201 | Се извршува Seq Scan на табелата recipe при пребарување и сортирање според total_time. |
| | 202 | |
| | 203 | 4. Иницијално извршување на погледот. |
| | 204 | |
| | 205 | 5. Explain plan (пред оптимизација): |
| | 206 | * Seq Scan на recipe |
| | 207 | * Sort operation по total_time |
| | 208 | * Execution Time: ~79 ms |
| | 209 | |
| | 210 | 6. Времето изминато во извршување на операциите insert и update изнесува: |
| | 211 | * INSERT: ~242 ms |
| | 212 | * UPDATE: ~1.188 s |
| | 213 | |
| | 214 | 7. Оптимизација: |
| | 215 | За да може базата брзо да ги подреди и филтрира рецептите според времето на подготовка, се додава индекс на колоната total_time. |
| | 216 | |
| | 217 | {{{ |
| | 218 | CREATE INDEX IF NOT EXISTS idx_recipe_total_time |
| | 219 | ON recipe(total_time); |
| | 220 | }}} |
| | 221 | |
| | 222 | 8. Explain plan (после оптимизација): |
| | 223 | * Bitmap Heap Scan |
| | 224 | * Bitmap Index Scan using idx_recipe_total_time |
| | 225 | * Execution Time: ~42 ms |
| | 226 | |
| | 227 | 9. Времето изминато во извршување на операциите insert и update по индексирање изнесува: |
| | 228 | * INSERT: ~148 ms |
| | 229 | * UPDATE: ~2.989 s |
| | 230 | |
| | 231 | 10. Заклучок: |
| | 232 | Со индексирање на total_time значително се подобри пребарувањето и сортирањето на брзи рецепти. |
| 109 | | Се користи за прикажување на форум постови заедно со корисник. |
| 110 | | |
| 111 | | Време на извршување: |
| 112 | | * Пред оптимизација: 1-2 секунди |
| 113 | | * После оптимизација: 50-150 ms |
| 114 | | |
| 115 | | Оптимизација: |
| 116 | | {{{ |
| 117 | | CREATE INDEX idx_forumpost_user_id ON forumpost(user_id); |
| 118 | | CREATE INDEX idx_forumpost_created_at ON forumpost(created_at); |
| 119 | | }}} |
| 120 | | |
| 121 | | Заклучок: Подобрени перформанси при прикажување и сортирање. |
| | 236 | |
| | 237 | 1. Примарен филтер за погледот forum_posts_view е user_id. |
| | 238 | |
| | 239 | 2. Случај на употреба: |
| | 240 | Погледот се користи за прикажување форум објави и пребарување на објави според корисник и датум. |
| | 241 | |
| | 242 | 3. Иницијално извршување на погледот. |
| | 243 | |
| | 244 | 4. Explain plan (пред оптимизација): |
| | 245 | * Gather operation |
| | 246 | * Parallel Seq Scan на forumpost |
| | 247 | * Nested Loop Left Join |
| | 248 | * Execution Time: ~3752 ms за user_id |
| | 249 | * Execution Time: ~4291 ms за user_id и created_at |
| | 250 | |
| | 251 | 5. Времето изминато во извршување на операциите insert и update изнесува: |
| | 252 | * INSERT: ~288 ms |
| | 253 | * UPDATE по id: ~64 ms |
| | 254 | * Масовен UPDATE: ~14.10 s |
| | 255 | |
| | 256 | 6. Оптимизација: |
| | 257 | Со цел да се забрза извршувањето се креираат индекси на user_id и created_at. |
| | 258 | |
| | 259 | {{{ |
| | 260 | CREATE INDEX idx_forumpost_user_id |
| | 261 | ON forumpost(user_id); |
| | 262 | |
| | 263 | CREATE INDEX idx_forumpost_created_at |
| | 264 | ON forumpost(created_at); |
| | 265 | }}} |
| | 266 | |
| | 267 | 7. Explain plan (после оптимизација): |
| | 268 | * Bitmap Heap Scan |
| | 269 | * Bitmap Index Scan using idx_forumpost_user_id |
| | 270 | * Bitmap Index Scan using idx_forumpost_created_at |
| | 271 | * Execution Time: ~0.211 ms |
| | 272 | * Execution Time: ~0.415 ms |
| | 273 | |
| | 274 | 8. Времето изминато во извршување на операциите insert и update по индексирање изнесува: |
| | 275 | * INSERT: ~96 ms |
| | 276 | * UPDATE: ~160 ms |
| | 277 | |
| | 278 | 9. Заклучок: |
| | 279 | Со индексирање на user_id и created_at значително се подобри пребарувањето и филтрирањето на форум објавите. |
| 125 | | Се користи за прикажување категории на рецепти. |
| 126 | | |
| 127 | | Време на извршување: |
| 128 | | * Пред оптимизација: 1-3 секунди |
| 129 | | * После оптимизација: 50-150 ms |
| 130 | | |
| 131 | | Оптимизација: |
| 132 | | {{{ |
| 133 | | CREATE INDEX idx_recipe_category_recipe_id ON recipe_category(recipe_id); |
| 134 | | CREATE INDEX idx_recipe_category_category_id ON recipe_category(category_id); |
| 135 | | }}} |
| 136 | | |
| 137 | | Заклучок: Значително подобрување поради join операциите. |
| 138 | | |
| 139 | | |
| 140 | | === Заклучок === |
| 141 | | |
| 142 | | Оптимизацијата на погледите со користење на индекси доведе до значително подобрување на перформансите, особено кај табели со голем број записи (10M+). Времето на извршување се намали од неколку секунди на милисекунди, што е прифатливо за продукциски систем. За погледи без филтри и join операции, индексите немаат значително влијание. |
| | 283 | |
| | 284 | 1. Примарен филтер за погледот recipe_categories_view е според recipe_id и category_id. |
| | 285 | |
| | 286 | 2. Случај на употреба: |
| | 287 | Погледот се користи за прикажување категории на рецепти и пребарување рецепти според категорија. |
| | 288 | |
| | 289 | 3. Иницијално извршување на погледот. |
| | 290 | |
| | 291 | 4. Explain plan (пред оптимизација): |
| | 292 | * Nested Loop Join |
| | 293 | * Parallel Seq Scan на recipe_category |
| | 294 | * Hash Join |
| | 295 | * Execution Time: ~61 ms за пребарување по category_id |
| | 296 | * Execution Time: ~0.277 ms за пребарување по recipe_id |
| | 297 | |
| | 298 | 5. Времето изминато во извршување на операциите insert и update изнесува: |
| | 299 | * INSERT: ~160 ms |
| | 300 | * UPDATE: ~302 ms |
| | 301 | |
| | 302 | 6. Оптимизација: |
| | 303 | Со цел да се забрза извршувањето се креираат индекси на recipe_id и category_id. |
| | 304 | |
| | 305 | {{{ |
| | 306 | CREATE INDEX idx_recipe_category_recipe_id |
| | 307 | ON recipe_category(recipe_id); |
| | 308 | |
| | 309 | CREATE INDEX idx_recipe_category_category_id |
| | 310 | ON recipe_category(category_id); |
| | 311 | }}} |
| | 312 | |
| | 313 | 7. Explain plan (после оптимизација): |
| | 314 | * Bitmap Heap Scan |
| | 315 | * Bitmap Index Scan using idx_recipe_category_category_id |
| | 316 | * Index Only Scan using recipe_category_pkey |
| | 317 | * Execution Time: ~225 ms за category_id |
| | 318 | * Execution Time: ~0.341 ms за recipe_id |
| | 319 | |
| | 320 | 8. Времето изминато во извршување на операциите insert и update по индексирање изнесува: |
| | 321 | * INSERT: ~117 ms |
| | 322 | * UPDATE: ~159 ms |
| | 323 | |
| | 324 | 9. Заклучок: |
| | 325 | Со индексирање на recipe_id и category_id се подобри пребарувањето и JOIN операциите кај категориите на рецепти. |