Changes between Version 3 and Version 4 of Optimization


Ignore:
Timestamp:
06/14/26 20:40:31 (5 days ago)
Author:
231184
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Optimization

    v3 v4  
    1 === hello world
     1= Оптимизација на прашалници и погледи =
     2
     3Во оваа фаза ќе ги анализираме погледите дефинирани во претходните фази преку прашалници базирани на реални сценарија кои ќе бидат присутни во апликацијата Rezervo. Целта е да се провери времето на извршување на прашалниците пред и после додавање на соодветни индекси, како и да се објасни зошто тие индекси ги подобруваат перформансите.
     4
     5Rezervo е систем за резервации кај занаетчии и даватели на услуги, каде што корисниците можат да пребаруваат достапни термини, да закажуваат, менуваат или откажуваат резервации, како и да оставаат рецензии за услугите.
     6
     7== 1. Анализа на поглед customer_appointments_view, преглед на резервации за конкретен корисник ==
     8
     9Овој поглед се користи за прикажување на сите активни или релевантни термини на одреден корисник. Во апликацијата ова би се користело на профилот на корисникот, каде што тој ги гледа своите закажани термини.
     10
     11Прашалникот кој го тестираме е:
     12
     13{{{
     14EXPLAIN ANALYZE
     15SELECT *
     16FROM customer_appointments_view
     17WHERE customer_id = 100;
     18}}}
     19
     20=== Време на извршување без индекс:
     21
     22**644.544 ms**
     23
     24Бидејќи прашалникот филтрира според `customer_id`, а во погледот не се потребни откажаните термини, креираме парцијален индекс врз табелата `appointment`. Со овој индекс се индексираат само редиците чиј статус не е `cancelled`, со што индексот е помал и поефикасен.
     25
     26{{{
     27CREATE INDEX IF NOT EXISTS idx_appointment_customer_not_cancelled
     28ON appointment(customer_id)
     29WHERE status <> 'cancelled';
     30
     31ANALYZE appointment;
     32}}}
     33
     34=== Време на извршување со индекс:
     35
     36**2.756 ms**
     37
     38Со додавање на индексот, времето на извршување се намали од **644.544 ms** на **2.756 ms**. Ова е значително подобрување бидејќи планерот повеќе нема потреба да ја скенира целата табела `appointment`, туку директно ги наоѓа редиците за конкретниот корисник.
     39
     40== 2. Анализа на поглед available_slots, пребарување на слободни термини за даден бизнис и датум ==
     41
     42Овој поглед се користи кога корисник пребарува достапни термини кај одреден бизнис за конкретен ден. Ова е еден од најчестите прашалници во системот, бидејќи секое закажување започнува со пребарување на слободни термини.
     43
     44Прашалникот кој го тестираме е:
     45
     46{{{
     47EXPLAIN ANALYZE
     48SELECT *
     49FROM available_slots
     50WHERE business_id = 1
     51AND date = CURRENT_DATE;
     52}}}
     53
     54=== Време на извршување без индекс:
     55
     56**429.479 ms**
     57
     58Погледот пребарува според `business_id`, `date` и дополнително ги зема само термините кои се достапни. Затоа креираме парцијален индекс кој ги покрива само термините каде што `is_available = TRUE`.
     59
     60{{{
     61CREATE INDEX IF NOT EXISTS idx_time_slot_available_business_date
     62ON time_slot(business_id, date)
     63WHERE is_available = TRUE;
     64
     65ANALYZE time_slot;
     66}}}
     67
     68=== Време на извршување со индекс:
     69
     70**1.090 ms**
     71
     72Со овој индекс времето се намали од **429.479 ms** на **1.090 ms**. Индексот е многу корисен бидејќи прашалникот најчесто бара само достапни термини, па нема потреба да се пребаруваат сите термини во табелата `time_slot`.
     73
     74== 3. Анализа на поглед review_summary, краток преглед на рецензии за бизнис ==
     75
     76Овој поглед се користи за прикажување на резиме за рецензии на одреден бизнис. Во апликацијата ова може да се користи на страната на бизнисот, каде што се прикажува просечна оценка, број на рецензии или распределба на оценки.
     77
     78Прашалникот кој го тестираме е:
     79
     80{{{
     81EXPLAIN ANALYZE
     82SELECT *
     83FROM review_summary
     84WHERE business_id = 1;
     85}}}
     86
     87=== Време на извршување без индекс:
     88
     89**627.643 ms**
     90
     91Бидејќи прашалникот филтрира според `business_id`, а во погледот се користи и `rating`, креираме сложен индекс врз двете колони.
     92
     93{{{
     94CREATE INDEX IF NOT EXISTS idx_review_business_rating_summary
     95ON review(business_id, rating);
     96
     97ANALYZE review;
     98}}}
     99
     100=== Време на извршување со индекс:
     101
     102**29.151 ms**
     103
     104Со додавање на индексот времето се намали од **627.643 ms** на **29.151 ms**. Индексот овозможува побрзо групирање и филтрирање на рецензиите за конкретен бизнис, бидејќи податоците се организирани според `business_id` и `rating`.
     105
     106== 4. Анализа на поглед review_details, детални рецензии според оценка ==
     107
     108Овој поглед се користи кога сакаме да ги прикажеме рецензиите кои имаат одредена оценка, на пример сите рецензии со оценка 5. Ова може да се користи за филтрирање на рецензии во корисничкиот интерфејс.
     109
     110Прашалникот кој го тестираме е:
     111
     112{{{
     113EXPLAIN ANALYZE
     114SELECT *
     115FROM review_details
     116WHERE rating = 5;
     117}}}
     118
     119=== Време на извршување без индекс:
     120
     121**800.553 ms**
     122
     123Бидејќи прашалникот филтрира според колоната `rating`, креираме индекс на оваа колона.
     124
     125{{{
     126CREATE INDEX IF NOT EXISTS idx_review_rating_details
     127ON review(rating);
     128
     129ANALYZE review;
     130}}}
     131
     132=== Време на извршување со индекс:
     133
     134**340.962 ms**
     135
     136Со додавање на индексот времето се намали од **800.553 ms** на **340.962 ms**. Подобрувањето е забележливо, но не е толку големо како кај претходните прашалници, бидејќи вредноста `rating = 5` може да се појавува кај голем број редици. Во таков случај индексот помага, но сепак мора да се прочита голем дел од табелата.
     137
     138== 5. Анализа на поглед customer_profile_view, профил на корисник со негови активности ==
     139
     140Овој поглед се користи за прикажување на профил на корисник, каде што можат да се прикажат неговите резервации, рецензии и други информации поврзани со активностите во системот.
     141
     142Прашалникот кој го тестираме е:
     143
     144{{{
     145EXPLAIN ANALYZE
     146SELECT *
     147FROM customer_profile_view
     148WHERE customer_id = 100;
     149}}}
     150
     151=== Време на извршување без индекс:
     152
     153**708.985 ms**
     154
     155За оптимизација на овој поглед креираме индекс врз табелата `review`, бидејќи погледот користи информации за рецензии поврзани со конкретен корисник.
     156
     157{{{
     158CREATE INDEX IF NOT EXISTS idx_review_customer_profile
     159ON review(customer_id, rating);
     160
     161ANALYZE appointment;
     162ANALYZE review;
     163}}}
     164
     165=== Време на извршување со индекс:
     166
     167**0.767 ms**
     168
     169Со додавање на индексот времето се намали од **708.985 ms** на **0.767 ms**. Ова е многу големо подобрување, бидејќи податоците за конкретниот корисник се наоѓаат директно преку индексот, наместо да се пребарува целата табела `review`.
     170
     171Во кодот беше разгледан и индексот:
     172
     173{{{
     174-- CREATE INDEX IF NOT EXISTS idx_appointment_customer_profile
     175--     ON appointment(customer_id, created_at);
     176}}}
     177
     178Овој индекс може да биде корисен доколку во погледот или во прашалниците често се користи сортирање или филтрирање според `created_at`. Во конкретниот тест, главното подобрување е постигнато со индексот врз `review(customer_id, rating)`.
     179
     180== 6. Анализа на поглед reschedule_overview, преглед на барања за промена на термин ==
     181
     182Овој поглед се користи за прикажување на барања за презакажување на термини. Во апликацијата ова би се користело од страна на бизнисот или вработениот за да ги види барањата кои се во статус `pending`.
     183
     184Прашалникот кој го тестираме е:
     185
     186{{{
     187EXPLAIN ANALYZE
     188SELECT *
     189FROM reschedule_overview
     190WHERE status = 'pending';
     191}}}
     192
     193За оптимизација креираме индекси врз колоните кои најчесто се користат во филтрирање и спојување на табелата `reschedule_request`.
     194
     195{{{
     196CREATE INDEX IF NOT EXISTS idx_reschedule_request_status
     197ON reschedule_request(status);
     198
     199CREATE INDEX IF NOT EXISTS idx_reschedule_request_old_slot_id
     200ON reschedule_request(old_slot_id);
     201
     202CREATE INDEX IF NOT EXISTS idx_reschedule_request_new_slot_id
     203ON reschedule_request(new_slot_id);
     204
     205ANALYZE reschedule_request;
     206}}}
     207
     208Потоа повторно го извршуваме прашалникот:
     209
     210{{{
     211EXPLAIN ANALYZE
     212SELECT *
     213FROM reschedule_overview
     214WHERE status = 'pending';
     215}}}
     216
     217Индексот `idx_reschedule_request_status` помага при филтрирање на барањата според статус, особено за чести прашалници како `status = 'pending'`.
     218
     219Индексите `idx_reschedule_request_old_slot_id` и `idx_reschedule_request_new_slot_id` помагаат при спојување со табелата за термини, бидејќи барањата за презакажување најчесто ги поврзуваат стариот и новиот термин преку овие колони.
     220
     221=== Време на извршување:
     222
     223Во овој дел треба да се внесат резултатите од `EXPLAIN ANALYZE` пред и после додавање на индексите.
     224
     225{{{
     226-- Пред оптимизација:   да се внесе измереното време
     227-- После оптимизација:  да се внесе измереното време
     228}}}
     229
     230== 7. Влијание на индексите врз insert/update операции ==
     231
     232Иако индексите значително го подобруваат читањето на податоците, тие можат да имаат мало влијание врз операциите за внесување и ажурирање. Причината е тоа што при секој `INSERT`, `UPDATE` или `DELETE`, базата мора да ги ажурира и индексите, не само главната табела.
     233
     234За тестирање на влијанието може да се користат следните прашалници:
     235
     236{{{
     237EXPLAIN ANALYZE
     238INSERT INTO review (customer_id, business_id, rating, comment, created_at)
     239VALUES (100, 1, 5, 'Benchmark review', CURRENT_TIMESTAMP);
     240}}}
     241
     242{{{
     243EXPLAIN ANALYZE
     244UPDATE review
     245SET rating = 4
     246WHERE customer_id = 100;
     247}}}
     248
     249{{{
     250EXPLAIN ANALYZE
     251INSERT INTO time_slot (business_id, date, start_time, end_time, is_available)
     252VALUES (1, CURRENT_DATE, TIME '10:00', TIME '10:30', TRUE);
     253}}}
     254
     255{{{
     256EXPLAIN ANALYZE
     257UPDATE time_slot
     258SET is_available = FALSE
     259WHERE business_id = 1
     260AND date = CURRENT_DATE;
     261}}}
     262
     263{{{
     264EXPLAIN ANALYZE
     265UPDATE reschedule_request
     266SET status = 'approved'
     267WHERE status = 'pending';
     268}}}
     269
     270Очекувано е индексите да внесат мал трошок при запишување, но бидејќи главните сценарија во апликацијата се пребарување на слободни термини, преглед на резервации и читање на рецензии, добивката кај `SELECT` прашалниците е многу поголема од потенцијалниот трошок кај `INSERT` и `UPDATE`.
     271
     272== 8. Заклучок ==
     273
     274Со додавање на соодветни индекси успеавме значително да ги подобриме перформансите на најважните прашалници во системот Rezervo.
     275
     276Најголеми подобрувања се забележуваат кај:
     277
     278||= Поглед =||= Пред оптимизација =||= После оптимизација =||
     279|| customer_appointments_view || 644.544 ms || 2.756 ms ||
     280|| available_slots || 429.479 ms || 1.090 ms ||
     281|| review_summary || 627.643 ms || 29.151 ms ||
     282|| review_details || 800.553 ms || 340.962 ms ||
     283|| customer_profile_view || 708.985 ms || 0.767 ms ||
     284|| reschedule_overview || да се внесе || да се внесе ||
     285
     286Најголемо забрзување има кај `customer_profile_view`, каде што времето се намали од **708.985 ms** на **0.767 ms**, како и кај `available_slots`, каде што пребарувањето на достапни термини се намали од **429.479 ms** на **1.090 ms**.
     287
     288Заклучуваме дека индексите се оправдани бидејќи ги оптимизираат најчестите кориснички сценарија во апликацијата:
     289
     290* преглед на резервации за корисник,
     291* пребарување на достапни термини,
     292* преглед и филтрирање на рецензии,
     293* приказ на кориснички профил,
     294* обработка на барања за презакажување.
     295
     296Иако индексите можат да имаат мал трошок при внесување и ажурирање на податоци, во овој систем читањето и пребарувањето се многу почести операции, па добивката во перформанси е значително поголема.