| 105 | | JOIN synergymed.company c ON ph.company_id = c.id |
| 106 | | JOIN synergymed.brandedmedicine bm ON ibm.branded_medicine_id = bm.id |
| 107 | | JOIN synergymed.manufacturer m ON bm.manufacturer_id = m.company_id |
| 108 | | JOIN synergymed.company mc ON m.company_id = mc.id |
| 109 | | GROUP BY c.company_name, bm.name, mc.company_name |
| 110 | | HAVING SUM(ibm.quantity) < 100 |
| 111 | | ORDER BY total_stock ASC, last_update DESC |
| 112 | | LIMIT 20; |
| | 101 | JOIN synergymed.company c ON ph.company_id = c.id |
| | 102 | WHERE ibm.branded_medicine_id = 6432 |
| | 103 | AND ibm.last_changed BETWEEN CURRENT_DATE - INTERVAL '6 months' AND CURRENT_DATE |
| | 104 | ORDER BY ibm.last_changed DESC |
| | 105 | LIMIT 50; |
| 119 | | EXPLAIN (ANALYZE, BUFFERS) |
| 120 | | SELECT u.username, |
| 121 | | p.issued_at, |
| 122 | | p.valid_to, |
| 123 | | m.name AS medicine_name |
| 124 | | FROM synergymed.prescription p |
| 125 | | JOIN synergymed.users u ON p.embg = u.e_mail -- пример мапирање, зависи од FK |
| 126 | | JOIN synergymed.medicine m ON p.medicine_id = m.id |
| 127 | | WHERE p.valid_to >= CURRENT_DATE |
| 128 | | AND u.username ILIKE '%ivan%' |
| 129 | | ORDER BY p.valid_to DESC; |
| | 120 | Seq Scan on inventory_brandedmedicine ibm |
| | 121 | Filter: ((branded_medicine_id = 6432) |
| | 122 | AND (last_changed <= CURRENT_DATE) |
| | 123 | AND (last_changed >= (CURRENT_DATE - '6 mons'::interval))) |
| | 124 | Rows Removed by Filter: 100032 |
| | 125 | Buffers: shared hit=541 |
| 132 | | |
| 133 | | **Пример за тестирање извештај од сценарио 4:**// |
| | 128 | Без индекс, postgres извршува seq scan на табелата inventory_brandedmedicine.// |
| | 129 | Во postgres постојат два начини на читање на табелите: ред по ред, секоја редица до крај (seq scan) и index scan.// |
| | 130 | // |
| | 131 | Можеме да забележиме дека:// |
| | 132 | - Сите 100.032 реда се прочитани.// |
| | 133 | - Ниеден ред не поминал филтер (rows=0).// |
| | 134 | - Дури и кога ќе има редови -> пак ќе мора да помине низ целата табела.// |
| | 135 | На останатите места каде што се користи index scan, е поради тоа што имаме join услови по PK и FK, PRIMARY KEY автоматски создава индекс -> затоа PostgreSQL прави |
| | 136 | index scan.// |
| | 137 | // |
| | 138 | === Со индекси: |
| | 139 | [[Image(2-index.PNG)]] |
| 136 | | EXPLAIN (ANALYZE, BUFFERS) |
| 137 | | SELECT m1.medicine_name AS medicine_a, |
| 138 | | m2.medicine_name AS medicine_b, |
| 139 | | mi.severity, |
| 140 | | mi.type, |
| 141 | | mi.description |
| 142 | | FROM synergymed.medicineinteraction mi |
| 143 | | JOIN synergymed.medicine m1 ON mi.medicine_id_1 = m1.id |
| 144 | | JOIN synergymed.medicine m2 ON mi.medicine_id_2 = m2.id |
| 145 | | WHERE mi.severity IN ('умерена', 'висока') |
| 146 | | ORDER BY mi.severity DESC, m1.medicine_name, m2.medicine_name |
| 147 | | LIMIT 50; |
| | 142 | Bitmap Index Scan on idx_inventorybm_bmid_lastchanged |
| | 143 | Index Cond: (branded_medicine_id = 6432 |
| | 144 | AND last_changed BETWEEN ...) |
| | 147 | Можеме да забележиме дека:// |
| | 148 | - Се користи bitmap index scan на композитниот индекс (branded_medicine_id, last_changed).// |
| | 149 | - Условот branded_medicine_id = 6432 AND last_changed BETWEEN ... се извршува директно преку индексот -> нема потреба да се чита целата табела.// |
| | 150 | - Наместо seq scan низ сите 100.032 реда, се пристапува само до оние редови што реално го исполнуваат условот.// |
| | 151 | - Сортирањето по last_changed DESC исто така е оптимизирано, бидејќи индексот е креиран со редослед по last_changed.// |
| | 152 | // |
| | 153 | Резултат: Execution Time падна од 5.229ms (со Seq Scan) на околу 0.1 ms со индекс.// |
| 151 | | ---- |
| 152 | | == **Споредба на извршување на извештај за сценарио 2, 3 и 4 со и без индекси**// |
| 153 | | **Споредба на извршување на извештај 2 со и без индекси**// |
| 154 | | // |
| 155 | | Без индекси:// |
| 156 | | // |
| 157 | | [[Image(2-noindex.PNG)]] |
| 158 | | // |
| 159 | | Со индекси: |
| 160 | | // |
| 161 | | [[Image(2-index.PNG)]] |
| 162 | | // |
| 163 | | // |
| 164 | | **Споредба на извршување на извештај 3 со и без индекси**// |
| 165 | | // |
| 166 | | Без индекси:// |
| 167 | | // |
| 168 | | [[Image(3-noindex.PNG)]] |
| 169 | | // |
| 170 | | Со индекси: |
| 171 | | // |
| 172 | | [[Image(3-index.PNG)]] |
| 173 | | // |
| 174 | | // |
| 175 | | **Споредба на извршување на извештај 4 со и без индекси**// |
| 176 | | // |
| 177 | | Без индекси:// |
| 178 | | // |
| 179 | | [[Image(4-noindex.PNG)]] |
| 180 | | // |
| 181 | | Со индекси: |
| 182 | | // |
| 183 | | [[Image(4-index.PNG)]] |
| 184 | | // |
| 185 | | // |
| 186 | | ---- |
| 187 | | **Анализа на извештај 2:**// |
| 188 | | Забележуваме дека извршувањето и без индекси е релативно брзо поради тоа што моментално базата нема голем број записи. Сепак, во реална примена каде што секоја аптека би имала илјадници записи и чести ажурирања на количини, индексите врз branded_medicine_id и last_changed би биле важни.// |
| 189 | | // |
| 190 | | **Анализа на извештај 3:**// |
| 191 | | И тука се гледа дека и без индекси пребарувањата се извршуваат брзо, бидејќи податоците се малку. Но во продукциска околина, каде секој клиент би имал десетици рецепти и системот постојано би проверувал дали тие се активни, индексите врз client_id, medicine_id и valid_to би биле клучни. Со нив филтрирањето на активни рецепти и пребарувањето по пациенти би станало скалабилно и одржливо дури и при голем обем на податоци.// |
| 192 | | // |
| 193 | | **Анализа на извештај 4:**// |
| 194 | | За извештај 4, забележуваме дека извршувањето е побрзо без индекс, бидејќи табелата во нашиот случај е релативно мала и PostgreSQL претпочита целосно последователно читање (Seq Scan) наместо да користи индекс. |
| 195 | | Индекс значи дополнителен I/O lookup и кај мали табели е непотребен “overhead”.// |
| 196 | | // |
| 197 | | **Заклучок:**// |
| 198 | | Сценарио 2 и 3: иако во тест околина индекси не носат голема добивка поради мал број записи, нивната примена е критична во реална продукциска средина каде табелите експоненцијално ќе растат.// |
| 199 | | // |
| 200 | | Сценарио 4: индекси теоретски се корисни, но кај навистина многу мали табели како во овој случај тие дури можат да бидат побавни. Сепак, со зголемување на бројот на интеракции (N:M релации со илјадници комбинации) индексот ќе ја покаже својата вистинска вредност.// |
| | 155 | |
| | 156 | |
| | 157 | |
| | 158 | |
| | 159 | |
| | 160 | |