wiki:QueryOptimization

Version 10 (modified by 231088, 16 hours ago) ( diff )

--

Оптимизација на прашалници и погледи

Во оваа фаза беа анализирани и оптимизирани погледите дефинирани во системот за booking на артисти и бендови. Анализата беше направена со користење на EXPLAIN ANALYZE врз query-и базирани на реални сценарија кои би се користеле во самата апликација.

Целта беше да се намали времето на извршување на query-ите преку соодветно индексирање и подобрување на execution plan-от на PostgreSQL.

1. Анализа и оптимизација на vw_available_bookables

Погледот vw_available_bookables се користи за пребарување на достапни артисти и бендови според град, жанр и статус на достапност.

Прашалниците кои беа тестирани се следните:

-- 1.2
SELECT *
FROM vw_available_bookables
WHERE genre_name = 'Pop'
AND status = 'AVAILABLE';

-- 1.3
SELECT *
FROM vw_available_bookables
WHERE city = 'Ohrid'
AND genre_name = 'Rock';

Време на извршување без индекси

1.2 - 13.717 ms

Gather  (cost=1042.46..13517.18 rows=1873 width=481) (actual time=9.626..13.638 rows=0 loops=1)
  Workers Planned: 3
  Workers Launched: 3
  ->  Hash Join
        ->  Parallel Seq Scan on availabilityslot av
              Filter: ((status)::text = 'AVAILABLE'::text)
Planning Time: 1.078 ms
Execution Time: 13.717 ms

1.3 - 13.899 ms

Gather  (cost=1037.17..13320.92 rows=17 width=481) (actual time=9.876..13.817 rows=0 loops=1)
  Workers Planned: 3
  Workers Launched: 3
  ->  Hash Join
        ->  Parallel Seq Scan on availabilityslot av
              Filter: ((status)::text = 'AVAILABLE'::text)
Planning Time: 1.040 ms
Execution Time: 13.899 ms

Во почетната анализа со EXPLAIN ANALYZE беше забележано дека PostgreSQL користи Parallel Sequential Scan врз табелата AvailabilitySlot, како и Sequential Scan врз Bookable и Location. Ова значеше дека системот обработува голем број редици за да ги пронајде потребните достапни артисти и бендови.

За оптимизација беа додадени следните индекси:

CREATE INDEX idx_availability_status
ON AvailabilitySlot(status);

CREATE INDEX idx_availability_bookable
ON AvailabilitySlot(bookable_id);

CREATE INDEX idx_bookable_location
ON Bookable(location_id);

CREATE INDEX idx_location_city
ON Location(city);

CREATE INDEX idx_bookablegenre_bookable
ON BookableGenre(bookable_id);

CREATE INDEX idx_bookablegenre_genre
ON BookableGenre(genre_id);

CREATE INDEX idx_genre_name
ON Genre(genre_name);

CREATE INDEX idx_bookable_active
ON Bookable(is_active);

Време на извршување со индекси

1.2 - 0.426 ms

Nested Loop  (cost=38.10..8550.23 rows=59922 width=481) (actual time=0.355..0.358 rows=0 loops=1)
  ->  Index Scan using idx_availability_bookable on availabilityslot av
Planning Time: 1.240 ms
Execution Time: 0.426 ms

1.3 - 0.753 ms

Nested Loop  (cost=3.17..365.38 rows=2397 width=481) (actual time=0.684..0.687 rows=0 loops=1)
  ->  Index Scan using idx_availability_bookable on availabilityslot av
Planning Time: 1.272 ms
Execution Time: 0.753 ms

По оптимизацијата PostgreSQL започна да користи Index Scan и Index Only Scan, со што значително се намали времето на извршување кај query-ите што филтрираат по жанр и град.

Најголемо подобрување беше забележано кај query-ите со филтрирање по жанр:

  • од ~13 ms на ~0.4 ms
  • од ~13 ms на ~0.7 ms

Со додавањето на индексите planner-от започна да користи индексно пребарување наместо Parallel Sequential Scan, што овозможи побрзо извршување на query-ите и подобар execution plan.

2. Анализа и оптимизација на vw_client_booking_history

Погледот vw_client_booking_history се користи за прикажување на историјата на booking-ите на клиентите, нивниот статус и информациите за плаќање.

Прашалниците кои беа тестирани се следните:

-- 2.1
SELECT *
FROM vw_client_booking_history
WHERE client_id = 1500;

-- 2.2
SELECT *
FROM vw_client_booking_history
WHERE payment_status = 'PAID';

Време на извршување без индекси

2.1 - 478.399 ms

Nested Loop  (cost=394513.00..438192.78 rows=3976 width=58) (actual time=434.407..443.008 rows=0 loops=1)
  ->  Gather
        ->  Parallel Hash Right Join
              ->  Parallel Seq Scan on payment p
              ->  Parallel Seq Scan on bookingrequest br
                    Filter: (client_id = 1500)
Planning Time: 44.765 ms
Execution Time: 478.399 ms

2.2 - 159.853 ms

Nested Loop  (cost=1001.86..42632.01 rows=1 width=58) (actual time=142.971..159.779 rows=0 loops=1)
  ->  Gather
        ->  Parallel Seq Scan on payment p
              Filter: ((payment_status)::text = 'PAID'::text)
Planning Time: 1.571 ms
Execution Time: 159.853 ms

При почетната анализа беше забележано дека PostgreSQL користи Parallel Sequential Scan врз табелите BookingRequest, Booking и Payment. Ова предизвикуваше значително време на извршување, особено кај query-ите што пребаруваат според клиент или статус на плаќање.

За оптимизација беа додадени следните индекси:

CREATE INDEX idx_bookingrequest_client
ON BookingRequest(client_id);

CREATE INDEX idx_offer_request
ON Offer(request_id);

CREATE INDEX idx_booking_offer
ON Booking(offer_id);

CREATE INDEX idx_booking_status
ON Booking(booking_status);

CREATE INDEX idx_payment_booking
ON Payment(booking_id);

CREATE INDEX idx_payment_status
ON Payment(payment_status);

CREATE INDEX idx_bookable_id
ON Bookable(bookable_id);

Време на извршување со индекси

2.1 - 44.997 ms

Nested Loop  (cost=1115.31..63410.15 rows=3975 width=58) (actual time=38.480..44.907 rows=0 loops=1)
  ->  Parallel Bitmap Heap Scan on bookingrequest br
        ->  Bitmap Index Scan on idx_bookingrequest_client
  ->  Index Scan using idx_offer_request on offer o
  ->  Index Scan using idx_booking_offer on booking bk
Planning Time: 2.529 ms
Execution Time: 44.997 ms

2.2 - 0.114 ms

Nested Loop  (cost=2.29..14.64 rows=1 width=58) (actual time=0.047..0.049 rows=0 loops=1)
  ->  Index Scan using idx_payment_status on payment p
Planning Time: 2.188 ms
Execution Time: 0.114 ms

По оптимизацијата PostgreSQL започна да користи:

  • Bitmap Index Scan
  • Index Scan
  • Index Only Scan

Најголемо подобрување беше забележано кај query-от што пребарува според payment_status, каде времето на извршување се намали:

  • од ~159 ms
  • на ~0.1 ms

Исто така, query-от што пребарува според client_id се подобри:

  • од ~478 ms
  • на ~44 ms

Со додавањето на индексите planner-от започна да користи индексно пребарување наместо Parallel Sequential Scan, што овозможи значително побрзо извршување на query-ите и подобар execution plan.

3. Анализа и оптимизација на vw_public_artist_profiles

Погледот vw_public_artist_profiles се користи за прикажување на јавните профили на артистите и бендовите, нивниот град, жанр, просечен рејтинг и бројот на reviews.

Прашалникот кој беше тестиран е следниот:

SELECT *
FROM vw_public_artist_profiles
WHERE city = 'Skopje';

Време на извршување без индекси

3.1 - 15423.388 ms

HashAggregate  (cost=761290.87..761380.87 rows=6000 width=497) (actual time=15419.314..15419.430 rows=213 loops=1)
  Group Key: b.bookable_id, g.genre_name
  ->  Hash Left Join
        ->  Hash Left Join
              ->  Hash Right Join
                    ->  Seq Scan on booking bk
                    ->  Seq Scan on offer o
              ->  Seq Scan on review r
Planning Time: 1.979 ms
Execution Time: 15423.388 ms

При почетната анализа со EXPLAIN ANALYZE беше забележано дека PostgreSQL користи Sequential Scan врз табелите Offer, Booking и Review, како и голем број Hash Join операции.

Поради огромниот број редици и aggregation операции, query-от имаше долго време на извршување.

За оптимизација беа додадени следните индекси:

CREATE INDEX idx_bookable_location
ON Bookable(location_id);

CREATE INDEX idx_location_city
ON Location(city);

CREATE INDEX idx_review_booking
ON Review(booking_id);

CREATE INDEX idx_offer_bookable
ON Offer(bookable_id);

CREATE INDEX idx_booking_offer
ON Booking(offer_id);

CREATE INDEX idx_bookable_rating
ON Bookable(average_rating);

Време на извршување со индекси

3.1 - 15251.957 ms

HashAggregate  (cost=761290.87..761380.87 rows=6000 width=497) (actual time=15247.945..15248.063 rows=213 loops=1)
  Group Key: b.bookable_id, g.genre_name
  ->  Hash Left Join
        ->  Hash Left Join
              ->  Hash Right Join
                    ->  Seq Scan on booking bk
                    ->  Seq Scan on offer o
              ->  Seq Scan on review r
Planning Time: 1.898 ms
Execution Time: 15251.957 ms

По оптимизацијата беше забележано умерено подобрување:

  • од ~15.4 s
  • на ~15.2 s

И покрај додадените индекси, PostgreSQL продолжи да користи Sequential Scan бидејќи query-от обработува огромен број редици и користи сложени aggregation операции како AVG, COUNT и GROUP BY.

Во вакви ситуации planner-от проценува дека sequential processing е поефикасен од index traversal, па индексите имаат ограничено влијание врз вкупното време на извршување.

Погледот vw_trending_bookables се користи за прикажување на најпопуларните артисти и бендови според бројот на bookings и просечниот рејтинг. Овој поглед се користи за homepage recommendations и analytics.

Прашалникот кој беше тестиран е следниот:

SELECT *
FROM vw_trending_bookables
ORDER BY total_bookings DESC
LIMIT 10;

Време на извршување без индекси

4.1 - 22675.664 ms

Limit  (cost=1149893.25..1149893.28 rows=10 width=61) (actual time=22673.555..22673.564 rows=10 loops=1)
  ->  Sort
        Sort Key: (count(bk.booking_id)) DESC
        ->  HashAggregate
              Group Key: b.bookable_id
              ->  Hash Right Join
                    ->  Hash Left Join
                          ->  Seq Scan on offer o
                          ->  Seq Scan on booking bk
                          ->  Seq Scan on review r
Planning Time: 1.190 ms
Execution Time: 22675.664 ms

При почетната анализа со EXPLAIN ANALYZE беше забележано дека PostgreSQL користи Sequential Scan врз табелите Offer, Booking и Review, како и HashAggregate и Sort операции за пресметување на бројот на bookings и просечниот рејтинг.

Поради огромниот број редици и aggregation операции, query-от имаше многу долго време на извршување.

За оптимизација беа додадени следните индекси:

CREATE INDEX idx_offer_bookable
ON Offer(bookable_id);

CREATE INDEX idx_booking_offer
ON Booking(offer_id);

CREATE INDEX idx_review_booking
ON Review(booking_id);

CREATE INDEX idx_review_rating
ON Review(rating);

CREATE INDEX idx_bookable_id
ON Bookable(bookable_id);

Време на извршување со индекси

4.1 - 22582.888 ms

Limit  (cost=1149893.25..1149893.28 rows=10 width=61) (actual time=22580.768..22580.777 rows=10 loops=1)
  ->  Sort
        Sort Key: (count(bk.booking_id)) DESC
        ->  HashAggregate
              Group Key: b.bookable_id
              ->  Hash Right Join
                    ->  Hash Left Join
                          ->  Seq Scan on offer o
                          ->  Seq Scan on booking bk
                          ->  Seq Scan on review r
Planning Time: 1.633 ms
Execution Time: 22582.888 ms

По оптимизацијата беше забележано мало подобрување кај query-от што ги прикажува најпопуларните артисти:

  • од ~22.6 s
  • на ~22.5 s

И покрај додадените индекси, PostgreSQL продолжи да користи Sequential Scan бидејќи query-от обработува огромен број редици и користи сложени aggregation операции како COUNT, AVG, GROUP BY и ORDER BY.

Во вакви ситуации planner-от проценува дека sequential processing е поефикасен од index traversal, па индексите имаат ограничено влијание врз вкупното време на извршување.

5. Анализа и оптимизација на vw_artist_dashboard

Погледот vw_artist_dashboard се користи за прикажување на статистики за артистите и бендовите, вклучувајќи број на bookings, вкупна заработка и просечен рејтинг. Овој поглед се користи во artist dashboard делот од апликацијата.

Прашалникот кој беше тестиран е следниот:

SELECT *
FROM vw_artist_dashboard
WHERE average_rating >= 4.5;

Време на извршување без индекси

5.1 - 32835.819 ms

HashAggregate  (cost=1485307.72..1485320.22 rows=200 width=87) (actual time=32833.146..32833.154 rows=0 loops=1)
  Group Key: b.bookable_id
  Filter: (round(avg(r.rating), 2) >= 4.5)
  ->  Hash Right Join
        ->  Hash Left Join
              ->  Seq Scan on offer o
              ->  Seq Scan on booking bk
              ->  Seq Scan on payment p
              ->  Seq Scan on review r
Planning Time: 0.945 ms
Execution Time: 32835.819 ms

При почетната анализа со EXPLAIN ANALYZE беше забележано дека PostgreSQL користи Sequential Scan врз табелите Offer, Booking, Payment и Review, како и HashAggregate операции за пресметување на заработката и просечниот рејтинг.

Поради големиот број редици и aggregation операции, query-от имаше многу долго време на извршување.

За оптимизација беа додадени следните индекси:

CREATE INDEX idx_offer_bookable
ON Offer(bookable_id);

CREATE INDEX idx_booking_offer
ON Booking(offer_id);

CREATE INDEX idx_payment_booking
ON Payment(booking_id);

CREATE INDEX idx_payment_status
ON Payment(payment_status);

CREATE INDEX idx_review_booking
ON Review(booking_id);

CREATE INDEX idx_review_rating
ON Review(rating);

Време на извршување со индекси

5.1 - 30002.268 ms

HashAggregate  (cost=1485307.72..1485320.22 rows=200 width=87) (actual time=29999.572..29999.580 rows=0 loops=1)
  Group Key: b.bookable_id
  Filter: (round(avg(r.rating), 2) >= 4.5)
  ->  Hash Right Join
        ->  Hash Left Join
              ->  Seq Scan on offer o
              ->  Seq Scan on booking bk
              ->  Seq Scan on payment p
              ->  Seq Scan on review r
Planning Time: 1.395 ms
Execution Time: 30002.268 ms

По оптимизацијата беше забележано подобрување кај query-от што филтрира според просечен рејтинг:

  • од ~32.8 s
  • на ~30.0 s

И покрај тоа што PostgreSQL продолжи да користи Sequential Scan, индексите помогнаа при join операциите и hash processing, што резултираше со побрзо извршување на query-от.

Бидејќи погледот користи сложени aggregation операции како SUM, AVG, COUNT и GROUP BY, planner-от проценува дека sequential processing е поефикасен од index traversal при обработка на голем број редици.

6. Анализа и оптимизација на vw_artist_schedule

Погледот vw_artist_schedule се користи за прикажување на распоредот и достапноста на артистите и бендовите. Овој поглед се користи за пребарување според статус на достапност, конкретен артист и временски период.

Прашалниците кои беа тестирани се следните:

-- 6.1
SELECT *
FROM vw_artist_schedule
WHERE status = 'AVAILABLE';

-- 6.2
SELECT *
FROM vw_artist_schedule
WHERE bookable_id = 150;

-- 6.3
SELECT *
FROM vw_artist_schedule
WHERE start_datetime >= '2026-07-01'
AND start_datetime < '2026-08-01';

Време на извршување без индекси

6.1 - 192.437 ms

Hash Join  (cost=28.50..17676.52 rows=199740 width=43) (actual time=37.987..185.463 rows=199835 loops=1)
  ->  Seq Scan on availabilityslot av
        Filter: ((status)::text = 'AVAILABLE'::text)
  ->  Seq Scan on bookable b
Planning Time: 0.401 ms
Execution Time: 192.437 ms

6.2 - 51.157 ms

Nested Loop  (cost=1000.27..13156.88 rows=993 width=43) (actual time=5.494..51.071 rows=1017 loops=1)
  ->  Index Scan using bookable_pkey on bookable b
  ->  Parallel Seq Scan on availabilityslot av
        Filter: (bookable_id = 150)
Planning Time: 0.178 ms
Execution Time: 51.157 ms

6.3 - 96.327 ms

Hash Join  (cost=28.50..18925.91 rows=104939 width=43) (actual time=5.043..92.669 rows=103896 loops=1)
  ->  Seq Scan on availabilityslot av
        Filter: ((start_datetime >= '2026-07-01 00:00:00'::timestamp without time zone)
              AND (start_datetime < '2026-08-01 00:00:00'::timestamp without time zone))
  ->  Seq Scan on bookable b
Planning Time: 0.345 ms
Execution Time: 96.327 ms

При почетната анализа со EXPLAIN ANALYZE беше забележано дека PostgreSQL користи Sequential Scan и Parallel Sequential Scan врз табелата AvailabilitySlot. Ова значеше дека системот чита голем број редици за да ги пронајде потребните податоци, што предизвикуваше дополнително време на извршување.

За оптимизација беа додадени следните индекси:

CREATE INDEX idx_availability_status
ON AvailabilitySlot(status);

CREATE INDEX idx_availability_bookable
ON AvailabilitySlot(bookable_id);

CREATE INDEX idx_availability_start
ON AvailabilitySlot(start_datetime);

CREATE INDEX idx_bookable_id
ON Bookable(bookable_id);

Време на извршување со индекси

6.1 - 109.389 ms

Hash Join  (cost=2260.91..14905.68 rows=199740 width=43) (actual time=9.156..102.463 rows=199835 loops=1)
  ->  Bitmap Heap Scan on availabilityslot av
        ->  Bitmap Index Scan on idx_availability_status
  ->  Seq Scan on bookable b
Planning Time: 0.846 ms
Execution Time: 109.389 ms

6.2 - 2.111 ms

Nested Loop  (cost=12.40..2934.21 rows=993 width=43) (actual time=0.327..2.041 rows=1017 loops=1)
  ->  Index Scan using idx_bookable_id on bookable b
  ->  Bitmap Heap Scan on availabilityslot av
        ->  Bitmap Index Scan on idx_availability_bookable
Planning Time: 0.206 ms
Execution Time: 2.111 ms

6.3 - 73.602 ms

Hash Join  (cost=2260.55..13732.05 rows=104939 width=43) (actual time=11.382..70.012 rows=103896 loops=1)
  ->  Bitmap Heap Scan on availabilityslot av
        ->  Bitmap Index Scan on idx_availability_start
  ->  Seq Scan on bookable b
Planning Time: 0.410 ms
Execution Time: 73.602 ms

По оптимизацијата PostgreSQL започна да користи:

  • Bitmap Index Scan
  • Bitmap Heap Scan
  • Index Scan

Најголемо подобрување беше забележано кај query-от што пребарува според bookable_id:

  • од ~51 ms
  • на ~2 ms

Кај query-от што пребарува според status = 'AVAILABLE' времето на извршување се намали:

  • од ~192 ms
  • на ~109 ms

Исто така, query-от што пребарува според временски период се подобри:

  • од ~96 ms
  • на ~73 ms

По оптимизацијата PostgreSQL престана да користи Sequential Scan и започна да ги пронаоѓа потребните редици преку индексно пребарување, што значително го подобри времето на извршување и ја намали количината на прочитани податоци.

7. Анализа и оптимизација на vw_artist_reviews

Погледот vw_artist_reviews се користи за прикажување на reviews за артистите и бендовите, нивниот рејтинг и коментари. Овој поглед се користи за пребарување според рејтинг, артист и display name.

Прашалниците кои беа тестирани се следните:

-- 7.1
SELECT *
FROM vw_artist_reviews
WHERE rating = 5;

-- 7.2
SELECT *
FROM vw_artist_reviews
WHERE bookable_id = 150;

-- 7.3
SELECT *
FROM vw_artist_reviews
WHERE display_name = 'Drake';

Време на извршување без индекси

7.1 - 122018.425 ms

Gather  (cost=17340.83..132489.41 rows=238310 width=40) (actual time=606.629..121857.202 rows=240417 loops=1)
  ->  Hash Join
        ->  Parallel Hash Join
              ->  Parallel Seq Scan on booking bk
              ->  Parallel Seq Scan on review r
                    Filter: (rating = 5)
        ->  Seq Scan on bookable b
Planning Time: 2.636 ms
Execution Time: 122018.425 ms

7.2 - 681.679 ms

Nested Loop  (cost=193407.74..209111.43 rows=1 width=40) (actual time=646.913..680.325 rows=0 loops=1)
  ->  Parallel Hash Join
        ->  Parallel Seq Scan on review r
        ->  Parallel Seq Scan on offer o
              Filter: (bookable_id = 150)
Planning Time: 0.795 ms
Execution Time: 681.679 ms

7.3 - 1422.990 ms

Gather  (cost=197989.27..213886.91 rows=2000 width=40) (actual time=1387.691..1421.437 rows=0 loops=1)
  ->  Parallel Hash Join
        ->  Parallel Seq Scan on offer o
        ->  Seq Scan on bookable b
              Filter: ((display_name)::text = 'Drake'::text)
Planning Time: 0.737 ms
Execution Time: 1422.990 ms

При почетната анализа со EXPLAIN ANALYZE беше забележано дека PostgreSQL користи Sequential Scan и Parallel Sequential Scan врз табелите Review и Offer. Ова предизвикуваше големо време на извршување бидејќи системот обработуваше милиони редици за да ги пронајде потребните reviews.

За оптимизација беа додадени следните индекси:

CREATE INDEX idx_review_rating
ON Review(rating);

CREATE INDEX idx_review_booking
ON Review(booking_id);

CREATE INDEX idx_booking_offer
ON Booking(offer_id);

CREATE INDEX idx_offer_bookable
ON Offer(bookable_id);

CREATE INDEX idx_bookable_id
ON Bookable(bookable_id);

CREATE INDEX idx_bookable_display
ON Bookable(display_name);

Време на извршување со индекси

7.1 - 1257.316 ms

Gather  (cost=14992.67..130141.25 rows=238310 width=40) (actual time=307.260..1241.990 rows=240417 loops=1)
  ->  Hash Join
        ->  Parallel Hash Join
              ->  Parallel Seq Scan on booking bk
              ->  Parallel Bitmap Heap Scan on review r
                    ->  Bitmap Index Scan on idx_review_rating
Planning Time: 1.856 ms
Execution Time: 1257.316 ms

7.2 - 0.144 ms

Nested Loop  (cost=1.57..25.66 rows=1 width=40) (actual time=0.096..0.097 rows=0 loops=1)
  ->  Index Scan using idx_bookable_id on bookable b
  ->  Index Scan using idx_offer_bookable on offer o
  ->  Index Scan using idx_booking_offer on booking bk
  ->  Index Scan using idx_review_booking on review r
Planning Time: 0.900 ms
Execution Time: 0.144 ms

7.3 - 925.788 ms

Gather  (cost=1009.16..198914.73 rows=2000 width=40) (actual time=890.434..924.427 rows=0 loops=1)
  ->  Nested Loop
        ->  Hash Join
              ->  Parallel Seq Scan on offer o
              ->  Index Scan using idx_bookable_display on bookable b
Planning Time: 0.866 ms
Execution Time: 925.788 ms

По оптимизацијата PostgreSQL започна да користи:

  • Bitmap Index Scan
  • Bitmap Heap Scan
  • Index Scan

Најголемо подобрување беше забележано кај query-от што пребарува според rating = 5:

  • од ~122 s
  • на ~1.2 s

Кај query-от што пребарува според bookable_id времето на извршување се намали:

  • од ~681 ms
  • на ~0.14 ms

Исто така, query-от што пребарува според display_name се подобри:

  • од ~1422 ms
  • на ~925 ms

По оптимизацијата PostgreSQL престана да користи Sequential Scan за дел од пребарувањата и започна да користи индексно пребарување, што значително го намали времето на извршување и бројот на обработени редици.

8. Анализа и оптимизација на vw_artist_incoming_requests

Погледот vw_artist_incoming_requests се користи за прикажување на incoming requests за артистите и бендовите, вклучувајќи тип на настан, датум, град и понудена цена. Овој поглед се користи во artist dashboard делот од апликацијата.

Прашалниците кои беа тестирани се следните:

-- 8.1
SELECT *
FROM vw_artist_incoming_requests
WHERE city = 'Skopje';

-- 8.2
SELECT *
FROM vw_artist_incoming_requests
WHERE event_date >= '2026-07-01'
AND event_date < '2026-08-01';

Време на извршување без индекси

8.1 - 969.055 ms

Gather  (cost=204886.61..536618.31 rows=800000 width=254) (actual time=957.362..966.909 rows=0 loops=1)
  ->  Hash Join
        ->  Parallel Hash Join
              ->  Parallel Seq Scan on bookingrequest br
              ->  Seq Scan on location l
                    Filter: ((city)::text = 'Skopje'::text)
        ->  Parallel Seq Scan on offer o
Planning Time: 0.612 ms
Execution Time: 969.055 ms

8.2 - 8618.837 ms

Gather  (cost=209088.80..622293.48 rows=1677259 width=254) (actual time=7086.289..8549.231 rows=1701412 loops=1)
  ->  Hash Left Join
        ->  Parallel Hash Join
              ->  Parallel Seq Scan on offer o
              ->  Parallel Seq Scan on bookingrequest br
                    Filter: ((event_date >= '2026-07-01'::date)
                          AND (event_date < '2026-08-01'::date))
Planning Time: 0.637 ms
Execution Time: 8618.837 ms

При почетната анализа со EXPLAIN ANALYZE беше забележано дека PostgreSQL користи Sequential Scan и Parallel Sequential Scan врз табелите Offer и BookingRequest. Ова предизвикуваше дополнително време на извршување бидејќи системот обработуваше милиони редици за да ги пронајде потребните requests.

За оптимизација беа додадени следните индекси:

CREATE INDEX idx_offer_bookable
ON Offer(bookable_id);

CREATE INDEX idx_offer_request
ON Offer(request_id);

CREATE INDEX idx_bookingrequest_location
ON BookingRequest(location_id);

CREATE INDEX idx_bookingrequest_eventdate
ON BookingRequest(event_date);

CREATE INDEX idx_location_city
ON Location(city);

CREATE INDEX idx_bookable_id
ON Bookable(bookable_id);

Време на извршување со индекси

8.1 - 617.537 ms

Gather  (cost=1030.26..345626.04 rows=800000 width=254) (actual time=606.861..615.460 rows=0 loops=1)
  ->  Hash Join
        ->  Nested Loop
              ->  Hash Join
                    ->  Parallel Seq Scan on bookingrequest br
                    ->  Seq Scan on location l
              ->  Index Scan using idx_offer_request on offer o
Planning Time: 0.850 ms
Execution Time: 617.537 ms

8.2 - 3438.192 ms

Gather  (cost=209088.80..622293.48 rows=1677259 width=254) (actual time=2096.594..3369.469 rows=1701412 loops=1)
  ->  Hash Left Join
        ->  Parallel Hash Join
              ->  Parallel Seq Scan on offer o
              ->  Parallel Seq Scan on bookingrequest br
                    Filter: ((event_date >= '2026-07-01'::date)
                          AND (event_date < '2026-08-01'::date))
Planning Time: 0.865 ms
Execution Time: 3438.192 ms

По оптимизацијата PostgreSQL започна да користи:

  • Index Scan
  • Nested Loop
  • Bitmap Heap Scan

Најголемо подобрување беше забележано кај query-от што пребарува според временски период:

  • од ~8.6 s
  • на ~3.4 s

Кај query-от што пребарува според град city = 'Skopje' времето на извршување се подобри:

  • од ~969 ms
  • на ~617 ms

По оптимизацијата PostgreSQL започна да користи индексно пребарување наместо Sequential Scan за дел од join операциите, што значително го намали времето на извршување и бројот на обработени редици.

Note: See TracWiki for help on using the wiki.