= Оптимизација на прашалници == Анализа и оптимизација на `Performer_Events` Овој поглед дава преглед на сите изведувачи и настаните на кои тие учествуваат, заедно со прецизниот термин на нивниот настап. {{{ CREATE VIEW "Performer_Events" AS SELECT p.performer_id, p.name AS performer_name, e.event_id, e.name AS event_name, eh.event_time FROM "Performer" p JOIN "Event_Happening_Performer" ehp ON p.performer_id = ehp.performer_id JOIN "Event_Happening" eh ON ehp.event_happening_id = eh.event_happening_id JOIN "Event" e ON eh.event_id = e.event_id; }}} ==== Без индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Performer_Events" WHERE performer_id = 10; }}} ||= QUERY PLAN =|| ||Nested Loop (cost\=1.14..73.38 rows\=7 width\=68) (actual time\=1505.862..3249.242 rows\=4 loops\=1)|| || -> Nested Loop (cost\=0.86..70.92 rows\=7 width\=37) (actual time\=1079.648..2259.465 rows\=4 loops\=1)|| || -> Index Scan using "Performer_pkey" on "Performer" p (cost\=0.28..8.30 rows\=1 width\=21) (actual time\=701.003..701.005 rows\=1 loops\=1)|| || Index Cond: (performer_id \= 10)|| || -> Nested Loop (cost\=0.57..62.55 rows\=7 width\=24) (actual time\=378.637..1558.442 rows\=4 loops\=1)|| || -> Index Only Scan using uq_performer_at_time on "Event_Happening_Performer" ehp (cost\=0.29..4.41 rows\=7 width\=16) (actual time\=90.817..90.838 rows\=4 loops\=1)|| || Index Cond: (performer_id \= 10)|| || Heap Fetches: 0|| || -> Index Scan using "Event_Happening_pkey" on "Event_Happening" eh (cost\=0.29..8.30 rows\=1 width\=24) (actual time\=366.888..366.889 rows\=1 loops\=4)|| || Index Cond: (event_happening_id \= ehp.event_happening_id)|| || -> Index Scan using "Event_pkey" on "Event" e (cost\=0.29..0.35 rows\=1 width\=39) (actual time\=247.432..247.432 rows\=1 loops\=4)|| || Index Cond: (event_id \= eh.event_id)|| ||Planning Time: 1816.633 ms|| ||Execution Time: 3249.314 ms|| * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Event_Happening_Performer" (event_happening_id, performer_id) VALUES (1, 10); }}} ||= QUERY PLAN =|| ||Insert on "Event_Happening_Performer" (cost\=0.00..0.01 rows\=0 width\=0) (actual time\=558.243..558.244 rows\=0 loops\=1)|| || -> Result (cost\=0.00..0.01 rows\=1 width\=16) (actual time\=0.001..0.002 rows\=1 loops\=1)|| ||Planning Time: 0.042 ms|| ||Trigger for constraint fk_ehp_event_happening: time\=826.105 calls\=1|| ||Trigger for constraint fk_ehp_performer: time\=40.075 calls\=1|| ||Execution Time: 1424.451 ms|| * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Event_Happening_Performer" SET performer_id = 11 WHERE event_happening_id = 1 AND performer_id = 10; }}} ||= QUERY PLAN =|| ||Update on "Event_Happening_Performer" (cost\=0.29..8.31 rows\=0 width\=0) (actual time\=0.219..0.219 rows\=0 loops\=1)|| || -> Index Scan using uq_performer_at_time on "Event_Happening_Performer" (cost\=0.29..8.31 rows\=1 width\=14) (actual time\=0.120..0.121 rows\=1 loops\=1)|| || Index Cond: ((performer_id \= 10) AND (event_happening_id \= 1))|| ||Planning Time: 0.139 ms|| ||Trigger for constraint fk_ehp_performer: time\=0.279 calls\=1|| ||Execution Time: 23.621 ms|| Погледот е бавен поради комплексни врски помеѓи четири табели што резултира со време од 3.2s. Индексите на performer_id и event_id го елиминираат целосното скенирање на табелите и овозможуваат инстантно поврзување на изведувачите со нивните настани. ==== Оптимизација: {{{ -- indexes for linking performers with specific event occurrences (M:N relationship) CREATE INDEX idx_ehp_performer_id ON "Event_Happening_Performer"(performer_id); CREATE INDEX idx_ehp_happening_id ON "Event_Happening_Performer"(event_happening_id); -- index for optimizing event lookups within scheduled event happenings CREATE INDEX idx_event_happening_event_id ON "Event_Happening"(event_id); }}} ==== Со индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Performer_Events" WHERE performer_id = 10; }}} ||= QUERY PLAN =|| ||Nested Loop (cost\=1.14..77.38 rows\=7 width\=68) (actual time\=0.251..0.479 rows\=4 loops\=1)|| || -> Nested Loop (cost\=0.86..74.92 rows\=7 width\=37) (actual time\=0.201..0.306 rows\=4 loops\=1)|| || -> Index Scan using "Performer_pkey" on "Performer" p (cost\=0.28..8.30 rows\=1 width\=21) (actual time\=0.093..0.094 rows\=1 loops\=1)|| || Index Cond: (performer_id \= 10)|| || -> Nested Loop (cost\=0.57..66.55 rows\=7 width\=24) (actual time\=0.105..0.207 rows\=4 loops\=1)|| || -> Index Only Scan using uq_performer_at_time on "Event_Happening_Performer" ehp (cost\=0.29..8.41 rows\=7 width\=16) (actual time\=0.062..0.065 rows\=4 loops\=1)|| || Index Cond: (performer_id \= 10)|| || Heap Fetches: 1|| || -> Index Scan using "Event_Happening_pkey" on "Event_Happening" eh (cost\=0.29..8.30 rows\=1 width\=24) (actual time\=0.032..0.032 rows\=1 loops\=4)|| || Index Cond: (event_happening_id \= ehp.event_happening_id)|| || -> Index Scan using "Event_pkey" on "Event" e (cost\=0.29..0.35 rows\=1 width\=39) (actual time\=0.041..0.041 rows\=1 loops\=4)|| || Index Cond: (event_id \= eh.event_id)|| ||Planning Time: 1.600 ms|| ||Execution Time: 0.533 ms|| * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Event_Happening_Performer" (event_happening_id, performer_id) VALUES (2, 10); }}} ||= QUERY PLAN =|| ||Insert on "Event_Happening_Performer" (cost\=0.00..0.01 rows\=0 width\=0) (actual time\=0.307..0.308 rows\=0 loops\=1)|| || -> Result (cost\=0.00..0.01 rows\=1 width\=16) (actual time\=0.001..0.001 rows\=1 loops\=1)|| ||Planning Time: 0.046 ms|| ||Trigger for constraint fk_ehp_event_happening: time\=0.332 calls\=1|| ||Trigger for constraint fk_ehp_performer: time\=0.169 calls\=1|| ||Execution Time: 0.833 ms|| * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Event_Happening_Performer" SET performer_id = 12 WHERE event_happening_id = 2 AND performer_id = 10; }}} ||= QUERY PLAN =|| ||Update on "Event_Happening_Performer" (cost\=0.29..8.31 rows\=0 width\=0) (actual time\=0.437..0.438 rows\=0 loops\=1)|| || -> Index Scan using idx_ehp_happening_id on "Event_Happening_Performer" (cost\=0.29..8.31 rows\=1 width\=14) (actual time\=0.174..0.175 rows\=1 loops\=1)|| || Index Cond: (event_happening_id \= 2)|| || Filter: (performer_id \= 10)|| || Rows Removed by Filter: 1|| ||Planning Time: 0.161 ms|| ||Trigger for constraint fk_ehp_performer: time\=0.271 calls\=1|| ||Execution Time: 0.763 ms|| == Анализа и оптимизација на `Venue_Layout` Овој поглед ја прикажува целосната структура на секој објект (сала), поврзувајќи ги поединечните седишта со соодветните сектори и името на објектот. {{{ CREATE VIEW "Venue_Layout" AS SELECT v.venue_id, v.name AS venue_name, s.section_id, s.name AS section_name, st.seat_id, st.seat_number FROM "Venue" v JOIN "Section" s ON v.venue_id = s.venue_id JOIN "Seat" st ON s.section_id = st.section_id; }}} ==== Без индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Venue_Layout" WHERE venue_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Seat" (seat_id, section_id, seat_number) SELECT COALESCE(MAX(seat_id), 0) + 1, 1, 999999 FROM "Seat"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Seat" SET seat_number = 888888 WHERE seat_number = 999999; }}} Времето за ажурирање од 312s е неприфатливо за интеракција со мапа на седишта во реално време. Со поставување индекси на seat_number и venue_id, пребарувањето и промената на статусот на седиштата се извршуваат за милисекунди наместо за неколку минути. ==== Оптимизација: {{{ -- index for linking seats to their respective sections CREATE INDEX idx_seat_section_id ON "Seat"(section_id); -- index for linking sections to venues CREATE INDEX idx_section_venue_id ON "Section"(venue_id); -- index for optimizing search and update operations on specific seat numbers CREATE INDEX idx_seat_number ON "Seat"(seat_number); }}} ==== Со индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Venue_Layout" WHERE venue_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Seat" (seat_id, section_id, seat_number) SELECT COALESCE(MAX(seat_id), 0) + 1, 1, 111222 FROM "Seat"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Seat" SET seat_number = 333444 WHERE seat_number = 111222; }}} == Анализа и оптимизација на `User_Tickets` Овој поглед ја прикажува целосната структура на секој објект (сала), поврзувајќи ги поединечните седишта со соодветните сектори и името на објектот. {{{ CREATE VIEW "User_Tickets" AS SELECT u.user_id, u.username, t.ticket_id, e.event_id, e.name AS event_name, tp.purchase_id, tp.qr_code, tr.refund_id, tr.refund_time FROM "User" u JOIN "Ticket_Purchase" tp ON u.user_id = tp.user_id JOIN "Ticket" t ON tp.ticket_id = t.ticket_id JOIN "Event_Happening" eh ON t.event_happening_id = eh.event_happening_id JOIN "Event" e ON eh.event_id = e.event_id LEFT JOIN "Ticket_Refund" tr ON tp.purchase_id = tr.purchase_id; }}} ==== Без индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "User_Tickets" WHERE user_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Ticket_Purchase" (purchase_id, ticket_id, user_id, qr_code, purchase_amount) SELECT COALESCE(MAX(purchase_id), 0) + 1, 1, 1, 'QR-TEST-CODE-001', 1200.00 FROM "Ticket_Purchase"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Ticket_Purchase" SET purchase_amount = 1500.00 WHERE user_id = 1 AND qr_code = 'QR-TEST-CODE-001'; }}} Приказот на историјата на билети трае предолги 251.9s, што го блокира корисничкиот профил. Индексот на user_id овозможува базата веднаш да ги лоцира билетите на конкретниот корисник без да ги пребарува сите трансакции во системот. ==== Оптимизација: {{{ -- index for linking ticket purchases to the specific tickets CREATE INDEX idx_ticket_purchase_ticket_id ON "Ticket_Purchase"(ticket_id); -- index for linking purchases to users CREATE INDEX idx_ticket_purchase_user_id ON "Ticket_Purchase"(user_id); -- index for the LEFT JOIN with refunds CREATE INDEX idx_ticket_refund_purchase_id ON "Ticket_Refund"(purchase_id); -- index for optimizing event lookups within scheduled event happenings CREATE INDEX idx_event_happening_event_id ON "Event_Happening"(event_id); }}} ==== Со индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "User_Tickets" WHERE user_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Ticket_Purchase" (purchase_id, ticket_id, user_id, qr_code, purchase_amount) SELECT COALESCE(MAX(purchase_id), 0) + 1, 1, 1, 'QR-TEST-CODE-002', 1200.00 FROM "Ticket_Purchase"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Ticket_Purchase" SET purchase_amount = 1350.00 WHERE user_id = 1 AND qr_code = 'QR-TEST-CODE-002'; }}} == Анализа и оптимизација на `Event_User_Ratings` Овој поглед овозможува детален пристап до поединечните коментари и оценки што секој корисник ги оставил за одреден термин на настан. {{{ CREATE VIEW "Event_User_Ratings" AS SELECT eh.event_happening_id, e.event_id, e.name AS event_name, u.user_id, u.username, ehr.rating_id, ehr.rating, ehr.comment FROM "Event" e JOIN "Event_Happening" eh ON e.event_id = eh.event_id JOIN "Event_Happening_Rating" ehr ON eh.event_happening_id = ehr.event_happening_id JOIN "User" u ON ehr.user_id = u.user_id; }}} ==== Без индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Event_User_Ratings" WHERE user_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Event_Happening_Rating" (rating_id, event_happening_id, user_id, rating, comment) SELECT COALESCE(MAX(rating_id), 0) + 1, 1, 1, 5, 'Test rating' FROM "Event_Happening_Rating"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Event_Happening_Rating" SET rating = 4, comment = 'New test rating' WHERE event_happening_id = 1 AND user_id = 1; }}} Без индекси, секое пребарување на оценките по корисник предизвикува непотребно оптоварување на меморијата преку Seq Scan. Индексирањето на user_id и event_happening_id обезбедува брза филтрација и поврзување на рејтинзите со соодветните термини на настаните. ==== Оптимизација: {{{ -- index for linking ratings to event happenings CREATE INDEX idx_ehr_happening_id ON "Event_Happening_Rating"(event_happening_id); -- index for linking ratings to users CREATE INDEX idx_ehr_user_id ON "Event_Happening_Rating"(user_id); }}} ==== Со индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Event_User_Ratings" WHERE user_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Event_Happening_Rating" (rating_id, event_happening_id, user_id, rating, comment) SELECT COALESCE(MAX(rating_id), 0) + 1, 2, 1, 5, 'Test rating' FROM "Event_Happening_Rating"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Event_Happening_Rating" SET rating = 6, comment = 'New test rating' WHERE event_happening_id = 1 AND user_id = 2; }}} == Анализа и оптимизација на `Event_Overall_Ratings` Овој поглед врши статистичка анализа на задоволството на публиката преку пресметување на просечната оцена и вкупниот број на рецензии за секој поединечен настан. {{{ CREATE VIEW "Event_Overall_Ratings" AS SELECT e.event_id, e.name AS event_name, eh.event_happening_id, eh.event_time, COUNT(ehr.rating_id) AS total_reviews, AVG(ehr.rating) AS average_rating FROM "Event" e JOIN "Event_Happening" eh ON e.event_id = eh.event_id JOIN "Event_Happening_Rating" ehr ON eh.event_happening_id = ehr.event_happening_id GROUP BY e.event_id, e.name, eh.event_happening_id, eh.event_time; }}} ==== Без индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Event_Overall_Ratings" WHERE event_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Event_Happening_Rating" (rating_id, event_happening_id, user_id, rating, comment) SELECT COALESCE(MAX(rating_id), 0) + 1, 1, 15, 9, 'Test rating' FROM "Event_Happening_Rating"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Event_Happening_Rating" SET rating = 8, comment = 'New test rating' WHERE event_happening_id = 1 AND user_id = 15; }}} Пресметката на просечни оценки бара постојано агрегирање на податоци, што е бавно при секој нов приказ. Композитен индекс на (event_happening_id, rating) овозможува математичките операции да се вршат директно врз индексот, забрзувајќи го приказот на почетната страна. ==== Оптимизација: {{{ -- composite index to speed up grouping and aggregate calculations (AVG, COUNT) CREATE INDEX idx_ehr_happening_id_rating ON "Event_Happening_Rating"(event_happening_id, rating); }}} ==== Со индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Event_Overall_Ratings" WHERE event_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Event_Happening_Rating" (rating_id, event_happening_id, user_id, rating, comment) SELECT COALESCE(MAX(rating_id), 0) + 1, 1, 20, 7, 'Test rating' FROM "Event_Happening_Rating"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Event_Happening_Rating" SET rating = 8, comment = 'New test rating' WHERE event_happening_id = 1 AND user_id = 15; }}} == Анализа и оптимизација на `Event_Financial_Summary` Овој поглед ги сумира финансиските резултати за секој настан, прикажувајќи го вкупниот број на продадени билети, нето приходот по одбивање на рефундациите и посебно издвоената заработка од административните такси при враќање на влезниците. {{{ CREATE VIEW "Event_Financial_Summary" AS SELECT e.event_id, e.name AS event_name, eh.event_happening_id, eh.event_time, COUNT(tp.purchase_id) AS total_tickets_sold, -- total revenue SUM(tp.purchase_amount) - SUM(CASE WHEN tr.refund_amount IS NOT NULL THEN tr.refund_amount ELSE 0 END) AS net_revenue, -- refund taxes SUM(CASE WHEN tr.refund_id IS NOT NULL THEN tp.purchase_amount - tr.refund_amount ELSE 0 END) AS refund_tax_profit FROM "Event" e JOIN "Event_Happening" eh ON e.event_id = eh.event_id JOIN "Ticket" t ON eh.event_happening_id = t.event_happening_id JOIN "Ticket_Purchase" tp ON t.ticket_id = tp.ticket_id LEFT JOIN "Ticket_Refund" tr ON tp.purchase_id = tr.purchase_id GROUP BY e.event_id, e.name, eh.event_happening_id, eh.event_time; }}} ==== Без индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Event_Financial_Summary" WHERE event_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Ticket_Purchase" (purchase_id, ticket_id, user_id, qr_code, purchase_time, purchase_amount) SELECT COALESCE(MAX(purchase_id), 0) + 1, 1, 1, 'QR-TEST-CODE-003', CURRENT_TIMESTAMP, 1500.00 FROM "Ticket_Purchase"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Ticket_Purchase" SET purchase_amount = 1800.00 WHERE qr_code = 'QR-TEST-CODE-003'; }}} Овој поглед има критично време на извршување од над 5 минути поради обработка на милиони трансакции. Индексите на ticket_id го намалуваат времето за 99%, овозможувајќи моментален преглед на приходите и рефундациите за секој настан. ==== Оптимизација: {{{ -- index for linking ticket purchases to the specific tickets CREATE INDEX idx_ticket_purchase_ticket_id ON "Ticket_Purchase"(ticket_id); -- index for the LEFT JOIN with refunds to calculate net revenue accurately CREATE INDEX idx_ticket_refund_purchase_id ON "Ticket_Refund"(purchase_id); -- index for linking tickets to scheduled events CREATE INDEX idx_ticket_event_happening_id ON "Ticket"(event_happening_id); }}} ==== Со индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Event_Financial_Summary" WHERE event_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Ticket_Purchase" (purchase_id, ticket_id, user_id, qr_code, purchase_time, purchase_amount) SELECT COALESCE(MAX(purchase_id), 0) + 1, 1, 2, 'QR-TEST-CODE-004', CURRENT_TIMESTAMP, 1400.00 FROM "Ticket_Purchase"; }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Ticket_Purchase" SET purchase_amount = 1700.00 WHERE qr_code = 'QR-TEST-CODE-004'; }}} == Анализа и оптимизација на `Future_Events` Овој поглед служи за динамично генерирање на репертоарот, прикажувајќи ги исклучиво претстојните настани во реално време преку филтрирање на изминатите термини. {{{ CREATE VIEW "Future_Events" AS SELECT e.event_id, e.name AS event_name, eh.event_happening_id, eh.event_time, v.venue_id, v.name AS venue_name, v.address_city AS city FROM "Event" e JOIN "Event_Happening" eh ON e.event_id = eh.event_id JOIN "Venue" v ON eh.venue_id = v.venue_id WHERE eh.event_time > CURRENT_TIMESTAMP; }}} ==== Без индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Future_Events" WHERE venue_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Event_Happening" (event_happening_id, event_id, venue_id, event_time, duration) VALUES ((SELECT MAX(event_happening_id) + 1 FROM "Event_Happening"), 1, 1, '2026-12-31 20:00:00', 120); }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Event_Happening" SET event_time = '2027-01-01 21:00:00' WHERE event_happening_id = (SELECT MAX(event_happening_id) FROM "Event_Happening"); }}} Времето на извршување е релативно ниско, но базата троши 4.258 ms само на планирање на секој поединечен запис. Бидејќи редовите не се подредени по време, системот мора да врши постојани споредби за секој настан. Заради ова, потребен е индекс кој ќе овозможи моментално лоцирање на идните настани без пребарување на целата табела. ==== Оптимизација: {{{ -- index for optimizing chronological filtering of future events CREATE INDEX idx_event_happening_time ON "Event_Happening"(event_time); -- index for accelerating lookups of events scheduled at specific venues CREATE INDEX idx_event_happening_venue_id ON "Event_Happening"(venue_id); -- composite index to optimize queries filtering both by venue and upcoming time slots CREATE INDEX idx_event_happening_venue_time ON "Event_Happening"(venue_id, event_time); }}} ==== Со индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Future_Events" WHERE venue_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Event_Happening" (event_happening_id, event_id, venue_id, event_time, duration) VALUES ((SELECT MAX(event_happening_id) + 1 FROM "Event_Happening"), 1, 1, '2026-11-15 19:00:00', 90); }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Event_Happening" SET event_time = '2026-11-20 20:00:00' WHERE event_happening_id = (SELECT MAX(event_happening_id) FROM "Event_Happening"); }}} == Анализа и оптимизација на `Available_Tickets` Овој поглед овозможува моментален увид во инвентарот на достапни седишта и автоматско враќање на рефундираните билети во понуда. {{{ CREATE VIEW "Available_Tickets" AS SELECT t.ticket_id, t.ticket_type, t.base_price, e.event_id, e.name AS event_name, eh.event_happening_id, eh.event_time, s.name AS section_name, st.seat_number FROM "Ticket" t JOIN "Event_Happening" eh ON t.event_happening_id = eh.event_happening_id JOIN "Event" e ON eh.event_id = e.event_id JOIN "Seat" st ON t.seat_id = st.seat_id JOIN "Section" s ON st.section_id = s.section_id WHERE t.is_available = TRUE; }}} ==== Без индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Available_Tickets" WHERE event_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Ticket" (ticket_id, ticket_type, base_price, is_available, event_happening_id, seat_id) VALUES ((SELECT MAX(ticket_id) + 1 FROM "Ticket"), 'Standard', 500.00, TRUE, 1, 999999); }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Ticket" SET base_price = 600.00 WHERE ticket_id = (SELECT MAX(ticket_id) FROM "Ticket"); }}} За овој поглед се трошат 948.13 ms бидејќи базата мора да пребарува низ 30 милиони записи. Овој процес вклучува скапи операции со трошок од 27455.75, каде се читаат милиони непотребни записи од дискот. Заради ова, потребен е индекс кој ќе ги издвои само достапните билети и ќе го елиминира ваквото чекање. ==== Оптимизација: {{{ -- partial index for rapid retrieval of only unsold tickets by filtering out sold ones CREATE INDEX idx_ticket_is_available_true ON "Ticket"(is_available) WHERE is_available = TRUE; -- index for linking tickets to scheduled events to accelerate event-based filtering CREATE INDEX idx_ticket_event_happening_id ON "Ticket"(event_happening_id); -- index for optimizing seat-based joins to retrieve venue layout details for each ticket CREATE INDEX idx_ticket_seat_id ON "Ticket"(seat_id); }}} ==== Со индекс: * '''SELECT''' {{{ EXPLAIN ANALYZE SELECT * FROM "Available_Tickets" WHERE event_id = 1; }}} * '''INSERT''' {{{ EXPLAIN ANALYZE INSERT INTO "Ticket" (ticket_id, ticket_type, base_price, is_available, event_happening_id, seat_id) VALUES ((SELECT MAX(ticket_id) + 1 FROM "Ticket"), 'Standard', 500.00, TRUE, 1, 888888); }}} * '''UPDATE''' {{{ EXPLAIN ANALYZE UPDATE "Ticket" SET base_price = 700.00 WHERE ticket_id = (SELECT MAX(ticket_id) FROM "Ticket"); }}}