Changes between Version 13 and Version 14 of QueryOptimization


Ignore:
Timestamp:
06/10/26 14:16:53 (10 days ago)
Author:
231040
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • QueryOptimization

    v13 v14  
    44
    55== Погледи
    6 - `v_staff_daily_schedule`: Го прикажува дневниот работен распоред за секој вработен и е наменет за користење од страна на самите вработени и рецепционерите.
    7 - `v_staff_open_slots`: Ги враќа сите слободни термини од по 15 минути во наредните 30 дена за секој активен вработен. 
    8 - `v_companies_by_category`: Се користи за филтрирање на компании и салони кои нудат одредена услуга или припаѓаат во категорија од интерес на клиентот.
    9 - `v_staff_service_menu`: Ги прикажува сите услуги кои одреден вработен може да ги понуди, заедно со неговата просечна оценка и бројот на извршени услуги.
    10 - `v_monthly_revenue_by_company`: Претставува месечен аналитички финансиски извештај за приходите на одредена компанија, наменет за сопствениците на салоните.
    11 - `v_future_appointments_client_o`: Ги прикажува сите идни закажани термини за одреден клиент, заедно со детали за вработениот, услугите и локацијата на салонот.
    12 - `v_client_dashboard`: Го прикажува профилот на клиентот по неговата најава, вклучувајќи поени за лојалност, следниот термин и потрошените пари во последните 30 дена. 
    13 - `v_invoice_detail_o`: Прикажува детална сметка по завршен термин со информации за плаќање, промо кодови, извршени услуги и податоци за клиентот и вработениот.
    14 - `v_staff_profile_dashboard`: Овозможува детален преглед на профилот на вработениот, неговата специјалност, улогите во системот и менаџирањето на неговиот работен календар.
     6
     7== v_staff_daily_schedule
     8
     9Овој view служи за приказ на дневниот распоред на вработените.
     10
     11Табелата `appointment` е главната табела бидејќи ги содржи сите информации за закажаните термини.
     12
     13Се спојуваат:
     14
     15* `user` за име на вработениот.
     16* `staff` за локацијата.
     17* `company_location` за адресата.
     18* `client` и `user` за информации за клиентот.
     19
     20Се користат два `LATERAL JOIN`:
     21
     22* Првиот ги агрегира сите улоги на вработениот од `staff_type`.
     23* Вториот ги агрегира сите услуги поврзани со терминот од `appointment_service`.
     24
     25Филтерот:
     26
     27{{{
     28WHERE status <> 'cancelled'
     29AND status <> 'completed'
     30}}}
     31
     32се извршува најрано со што значително се намалува бројот на обработени термини.
     33
     34Функцијата `LEAD()` пресметува временски јаз помеѓу два последователни термини без дополнителни self-join операции.
     35
     36---
     37
     38== v_staff_open_slots
     39
     40Овој view ги враќа сите слободни термини за закажување.
     41
     42Најпрво се креираат три мали агрегирани множества:
     43
     44* `staff_roles`
     45* `staff_services`
     46* `staff_rating`
     47
     48Со ова агрегирањето се извршува само еднаш.
     49
     50Главната табела е `staff_time_slot`.
     51
     52Филтрите:
     53
     54{{{
     55appointment_id IS NULL
     56slot_start >= NOW()
     57slot_start < NOW() + INTERVAL '30 days'
     58}}}
     59
     60се применуваат веднаш.
     61
     62Потоа се прави JOIN со:
     63
     64* `staff`
     65* `user`
     66* `company_location`
     67
     68и LEFT JOIN со:
     69
     70* `blocked_time`
     71
     72за елиминација на блокираните термини.
     73
     74Со условот:
     75
     76{{{
     77b.block_id IS NULL
     78}}}
     79
     80се задржуваат само реално достапните слотови.
     81
     82---
     83
     84== v_companies_by_category
     85
     86Овој view овозможува пребарување компании според категорија и услуги.
     87
     88CTE `company_services` прво ги агрегира сите активни услуги по компанија.
     89
     90Филтерот:
     91
     92{{{
     93WHERE s.is_active = TRUE
     94}}}
     95
     96се применува пред агрегацијата.
     97
     98Потоа се приклучуваат:
     99
     100* `company_company_category`
     101* `company_category`
     102* `company`
     103
     104На овој начин главниот SELECT работи со значително помал број редови.
     105
     106---
     107
     108== v_staff_service_menu
     109
     110Овој view прикажува кои услуги ги нуди секој вработен.
     111
     112Во CTE `staff_service_ratings` однапред се пресметуваат:
     113
     114* просечна оцена
     115* број на рецензии
     116* број на извршувања
     117
     118Само термините со статус:
     119
     120{{{
     121completed
     122}}}
     123
     124учествуваат во пресметката.
     125
     126Ова значително ја намалува количината на податоци бидејќи не се анализираат активни или откажани термини.
     127
     128---
     129
     130== v_monthly_revenue_by_company
     131
     132Овој view служи за финансиски извештаи.
     133
     134Се користат само табелите:
     135
     136* `invoice`
     137* `appointment`
     138* `company_location`
     139* `company`
     140
     141Бидејќи `invoice` е значително помала од `appointment_service`, пресметката е многу поефикасна.
     142
     143Сите финансиски агрегати:
     144
     145* SUM
     146* AVG
     147* COUNT
     148
     149се пресметуваат во една единствена GROUP BY операција.
     150
     151---
     152
     153== v_future_appointments_client_o
     154
     155Овој view ги враќа идните термини на клиентите.
     156
     157Филтерот:
     158
     159{{{
     160appointment_date >= CURRENT_DATE
     161status <> 'cancelled'
     162}}}
     163
     164се применува уште на почетокот.
     165
     166Со тоа се елиминираат сите историски записи.
     167
     168Се користи `LATERAL JOIN` за агрегација на услугите на секој термин поединечно наместо глобално GROUP BY врз целата табела `appointment_service`.
     169
     170За овој view е креиран индекс:
     171
     172{{{
     173idx_appointment_client_future
     174}}}
     175
     176бидејќи пребарувањето најчесто се врши според клиент и датум.
     177
     178---
     179
     180== v_client_dashboard
     181
     182Овој view е наменет за почетниот екран на клиентот.
     183
     184Се користат две CTE структури:
     185
     186* `upcoming`
     187* `recent_spend`
     188
     189Тие однапред ги пресметуваат:
     190
     191* идните термини
     192* потрошувачката во последните 30 дена
     193
     194Потоа главниот SELECT само ги приклучува готовите агрегирани резултати.
     195
     196Ова е поефикасно отколку секој пат да се пресметуваат агрегатите за секој клиент одново.
     197
     198---
     199
     200== mv_staff_avg_rating
     201
     202Ова е Materialized View.
     203
     204Наместо просечниот рејтинг да се пресметува секој пат кога се отвора профил на вработен, резултатот однапред се чува физички во базата.
     205
     206Предности:
     207
     208* многу побрзо читање
     209* помал број JOIN операции
     210* помал CPU трошок
     211
     212Се освежува преку:
     213
     214{{{
     215REFRESH MATERIALIZED VIEW CONCURRENTLY
     216}}}
     217
     218што овозможува истовремено користење на податоците.
     219
     220---
     221
     222== v_staff_profile_m
     223
     224Овој view прикажува целосен профил на вработен.
     225
     226Наместо повторно да се пресметуваат оценки од `review`, се користи:
     227
     228{{{
     229mv_staff_avg_rating
     230}}}
     231
     232што значително го намалува времето на извршување.
     233
     234Дополнително се користат два `LATERAL JOIN`:
     235
     236* агрегирање на услуги
     237* агрегирање на улоги
     238
     239Само активни корисници учествуваат во резултатот:
     240
     241{{{
     242WHERE u.is_active = TRUE
     243}}}
     244
     245---
     246
     247== v_invoice_detail_o
     248
     249Овој view е најдеталниот финансиски поглед.
     250
     251Главната табела е `invoice`, бидејќи фактурите се значително помалку од сите термини и услуги во системот.
     252
     253Се користат три `LATERAL JOIN`:
     254
     255* агрегација на услуги од терминот
     256* агрегација на промо кодови
     257* агрегација на улоги на вработениот
     258
     259Со ова секоја агрегација се извршува само за конкретната фактура.
     260
     261Овој пристап е поефикасен од глобални GROUP BY операции над целата база.
     262
     263---
     264
     265== Индекси
     266
     267Во решението се користи минимален број индекси:
     268
     269* `idx_appointment_client_future`
     270* индекс над `mv_staff_avg_rating`
     271* `idx_appointment_staff_rating`
     272
     273Целта е да се избегне прекумерно индексирање кое би ја забавило работата при INSERT, UPDATE и DELETE операции.
     274
     275Избраните индекси покриваат само најчестите пребарувања:
     276
     277* идни термини по клиент
     278* рејтинзи по вработен
     279* профил на вработен
     280
     281Со ова се постигнува баланс помеѓу брзина на читање и брзина на запишување на податоци.