| 1134 | | Во вакви ситуации planner-от проценува дека sequential processing е поефикасен за обработка на огромен број редици, па индексите имаат ограничено влијание врз aggregation и join операциите. |
| | 1126 | Во вакви ситуации planner-от проценува дека sequential processing е поефикасен за обработка на огромен број редици, па индексите имаат ограничено влијание врз aggregation и join операциите. Поради ова, беше одлучено да се примени дополнителна оптимизација преку Материјализиран Поглед. |
| | 1127 | |
| | 1128 | === Оптимизација со Материјализиран Поглед === |
| | 1129 | Бидејќи индексите не можеа значително да го подобрат времето на извршување поради огромниот број редици кои се враќаат (4 милиони), беше креиран Материјализиран Поглед ({{{MATERIALIZED VIEW}}}) кој ги зачувува резултатите физички на диск и овозможува побрзо пребарување без да се поминува низ сите join операции секој пат. |
| | 1130 | {{{ |
| | 1131 | CREATE MATERIALIZED VIEW mv_pending_payments AS |
| | 1132 | SELECT |
| | 1133 | p.payment_id, |
| | 1134 | bk.booking_id, |
| | 1135 | b.bookable_id, |
| | 1136 | b.display_name, |
| | 1137 | p.amount, |
| | 1138 | p.payment_status, |
| | 1139 | br.event_date, |
| | 1140 | l.city |
| | 1141 | FROM Payment p |
| | 1142 | JOIN Booking bk ON p.booking_id = bk.booking_id |
| | 1143 | JOIN Offer o ON bk.offer_id = o.offer_id |
| | 1144 | JOIN Bookable b ON o.bookable_id = b.bookable_id |
| | 1145 | JOIN BookingRequest br ON o.request_id = br.request_id |
| | 1146 | LEFT JOIN Location l ON br.location_id = l.location_id; |
| | 1147 | |
| | 1148 | CREATE UNIQUE INDEX idx_mv_payments_payment_id |
| | 1149 | ON mv_pending_payments(payment_id); |
| | 1150 | |
| | 1151 | CREATE INDEX idx_mv_payments_status |
| | 1152 | ON mv_pending_payments(payment_status); |
| | 1153 | |
| | 1154 | CREATE INDEX idx_mv_payments_city |
| | 1155 | ON mv_pending_payments(city); |
| | 1156 | |
| | 1157 | CREATE INDEX idx_mv_payments_event_date |
| | 1158 | ON mv_pending_payments(event_date); |
| | 1159 | }}} |
| | 1160 | |
| | 1161 | === Време на извршување со Материјализиран Поглед === |
| | 1162 | '''9.1 - 866.538 ms''' |
| | 1163 | {{{ |
| | 1164 | Seq Scan on mv_pending_payments (cost=0.00..89763.15 rows=4001532 width=49) (actual time=0.059..731.011 rows=4001410 loops=1) |
| | 1165 | Filter: ((payment_status)::text = 'PENDING'::text) |
| | 1166 | Planning Time: 0.468 ms |
| | 1167 | Execution Time: 866.538 ms |
| | 1168 | }}} |
| | 1169 | |
| | 1170 | По креирањето на Материјализираниот Поглед беше забележано подобрување: |
| | 1171 | * од ~10.0 s (со индекси) |
| | 1172 | * на ~866 ms (со Материјализиран Поглед) |
| | 1173 | |
| | 1174 | Подобрувањето е присутно, меѓутоа PostgreSQL сè уште користи {{{Seq Scan}}} врз Материјализираниот Поглед бидејќи query-от враќа речиси сите редици (4 милиони од вкупно 4 милиони). Во ваква ситуација index scan е поскап од sequential scan бидејќи нема селективност — скоро секоја редица го задоволува филтерот {{{payment_status = 'PENDING'}}}. |
| | 1175 | |
| | 1176 | Главното подобрување доаѓа од тоа што сложените {{{JOIN}}} операции меѓу {{{Payment}}}, {{{Booking}}}, {{{Offer}}}, {{{Bookable}}} и {{{BookingRequest}}} се пресметани однапред и зачувани, па PostgreSQL скенира само еден објект наместо пет табели. |
| | 1177 | |
| | 1178 | За да останат податоците ажурирани, Материјализираниот Поглед се освежува по секоја промена на статусот на плаќање: |
| | 1179 | {{{ |
| | 1180 | REFRESH MATERIALIZED VIEW CONCURRENTLY mv_pending_payments; |
| | 1181 | }}} |