= Мерење на перформанси Извршена е анализа на перформансите на базата film_rental во PostgreSQL. Се споредуваат неоптимизирани табели и оптимизирани табели: * rental_copy - непартиционирана табела, користена како почетна состојба за споредба; * rental - партиционирана табела според rental_date, со дополнителни индекси; * payment_copy - непартиционирана табела за плаќања; * payment - партиционирана табела според payment_date, со индекс за датум и вработен. За оваа анализа беше користено pgbench. Секој тест се извршува со повеќе паралелни клиенти, при што се мерат просечна латентност, standard deviation и TPS односно број на трансакции во секунда. Standard deviation покажува колку варира времето на извршување околу просечната латентност, па помала вредност значи постабилни и попредвидливи перформанси. Пример за извршување на benchmark тест: {{{ pgbench -n -U admin -d film_rental -c 10 -j 2 -T 60 -f /tmp/movie_recommendation_rental_copy.sql -l --log-prefix=/tmp/movie_recommendation_rental_copy_c10 }}} Каде: * -n означува дека pgbench не ја иницијализира стандардната pgbench шема; * -U admin е корисникот со кој се поврзува кон базата; * -d film_rental е базата врз која се извршува тестот; * -c 10 означува 10 паралелни клиенти; * -j 2 означува 2 работни нишки; * -T 60 означува времетраење од 60 секунди; * -f ја задава SQL датотеката што се извршува. * --log-prefix ја задава патеката и префиксот на log датотеките во кои pgbench ги запишува резултатите. Истата команда се повторуваше со различен број клиенти, на пример 10, 20, 30 и 50, и со SQL датотеки за неоптимизираната и оптимизираната верзија. За пресметување на standard deviation од pgbench log датотеките се користеше следната awk команда: {{{ awk ' $3 ~ /^[0-9]+$/ { n++; x=$3/1000; sum+=x; sumsq+=x*x } END { mean=sum/n; stddev=sqrt((sumsq - (sum*sum/n))/(n-1)); printf "transactions=%d\nmean=%.3f ms\nstddev=%.3f ms\n", n, mean, stddev } ' /tmp/movie_recommendation_rental_copy_c10* }}} Во log датотеките што ги генерира pgbench, секој ред претставува една извршена трансакција. Третата колона ($3) го содржи времето на извршување на таа трансакција, изразено во микросекунди. Бидејќи во табелите резултатите се прикажуваат во милисекунди, вредноста од третата колона се дели со 1000. Потоа од сите добиени вредности се пресметуваат просечната латентност и standard deviation. == Детални резултати === Q1 - Movie Recommendation Прашалникот прави препорака на филмови за конкретен корисник. Се анализираат претходните изнајмувања, омилените категории, рејтинзите и популарноста на филмовите во 2024 година. {{{ WITH customer_history AS ( SELECT DISTINCT f.film_id, f.rating, fc.category_id FROM rental_copy r JOIN inventory i ON r.inventory_id = i.inventory_id JOIN film f ON i.film_id = f.film_id JOIN film_category fc ON f.film_id = fc.film_id WHERE r.customer_id = 101 ), preferred_categories AS ( SELECT category_id, COUNT(*) AS category_score FROM customer_history GROUP BY category_id ), candidate_films AS ( SELECT f.film_id, f.title, f.rating, fc.category_id, pc.category_score FROM film f JOIN film_category fc ON f.film_id = fc.film_id JOIN preferred_categories pc ON fc.category_id = pc.category_id WHERE NOT EXISTS ( SELECT 1 FROM customer_history ch WHERE ch.film_id = f.film_id ) ), film_popularity AS ( SELECT i.film_id, COUNT(r.rental_id) AS rental_count FROM rental_copy r JOIN inventory i ON r.inventory_id = i.inventory_id WHERE r.rental_date >= DATE '2024-01-01' AND r.rental_date < DATE '2025-01-01' GROUP BY i.film_id ) SELECT cf.film_id, cf.title, cf.rating, c.name AS category, cf.category_score, COALESCE(fp.rental_count, 0) AS yearly_rentals, (cf.category_score * 10 + COALESCE(fp.rental_count, 0)) AS recommendation_score FROM candidate_films cf JOIN category c ON cf.category_id = c.category_id LEFT JOIN film_popularity fp ON cf.film_id = fp.film_id WHERE cf.rating IN ( SELECT rating FROM customer_history ) ORDER BY recommendation_score DESC, cf.title LIMIT 10; }}} За оптимизираната верзија се користи истата логика, но наместо rental_copy се користи партиционираната табела rental. || '''Clients''' || '''Threads''' || '''rental_copy latency''' || '''rental_copy stddev''' || '''rental_copy TPS''' || '''rental latency''' || '''rental stddev''' || '''rental TPS''' || '''Промена''' || || 10 || 2 || 2345.556 ms || 945.171 ms || 4.263 || 1653.931 ms || 549.645 ms || 6.046 || ~29.5% побрзо || || 20 || 4 || 4820.854 ms || 1526.728 ms || 4.149 || 3020.244 ms || 889.134 ms || 6.622 || ~37.4% побрзо || || 50 || 4 || 9811.989 ms || 2272.239 ms || 5.096 || 7444.747 ms || 1702.896 ms || 6.716 || ~24.1% побрзо || Q1 покажува подобрување кај оптимизираната табела кај сите нивоа на конкурентност. Кај 10 клиенти латентноста се намалува од 2345.556 ms на 1653.931 ms, а кај 50 клиенти од 9811.989 ms на 7444.747 ms. Standard deviation исто така е помала кај оптимизираната верзија. Кај 10 клиенти се намалува од 945.171 ms на 549.645 ms, а кај 50 клиенти од 2272.239 ms на 1702.896 ms. Ова покажува дека партиционирањето и индексите не само што го намалуваат просечното време на извршување, туку го прават извршувањето постабилно. === Q2 - Popular Films 2024 Прашалникот ги пресметува најизнајмуваните филмови во 2024 година. Се користи филтер по датум, спојување со inventory и film, групирање по филм и сортирање според бројот на изнајмувања. {{{ SELECT f.film_id, f.title, f.rating, COUNT(r.rental_id) AS rental_count FROM rental_copy r JOIN inventory i ON r.inventory_id = i.inventory_id JOIN film f ON i.film_id = f.film_id WHERE r.rental_date >= DATE '2024-01-01' AND r.rental_date < DATE '2025-01-01' GROUP BY f.film_id, f.title, f.rating ORDER BY rental_count DESC LIMIT 20; }}} За оптимизираната верзија се користи истата логика, но наместо rental_copy се користи партиционираната табела rental. || '''Clients''' || '''Threads''' || '''rental_copy latency''' || '''rental_copy stddev''' || '''rental_copy TPS''' || '''rental latency''' || '''rental stddev''' || '''rental TPS''' || '''Промена''' || || 10 || 4 || 2183.371 ms || 944.412 ms || 4.580 || 1545.473 ms || 584.405 ms || 6.471 || ~29.2% побрзо || || 20 || 4 || 3769.550 ms || 1473.425 ms || 5.306 || 3215.116 ms || 1297.115 ms || 6.221 || ~14.7% побрзо || || 30 || 4 || 5653.717 ms || 1793.595 ms || 5.306 || 4893.620 ms || 1679.520 ms || 6.130 || ~13.4% побрзо || || 50 || 4 || 10163.130 ms || 3034.697 ms || 4.920 || 7924.103 ms || 2330.346 ms || 6.310 || ~22.0% побрзо || Q2 покажува подобри резултати кај партиционираната табела. Латентноста е помала кај сите тестирани нивоа на конкурентност, а TPS е повисок. Standard deviation исто така е помала кај оптимизираната верзија, што покажува постабилно време на извршување. Иако прашалникот содржи GROUP BY и ORDER BY, партиционирањето по rental_date и индексот врз rental_date, inventory_id помагаат затоа што филтерот е ограничен на 2024 година. === Q3 - Monthly Revenue Прашалникот пресметува месечен приход по продавница за 2024 година. Се пресметуваат број на плаќања, вкупен приход, просечна, минимална и максимална уплата. {{{ SELECT date_trunc('month', p.payment_date) AS month, s.store_id, COUNT(p.payment_id) AS payments_count, SUM(p.amount) AS total_revenue, AVG(p.amount) AS avg_payment, MIN(p.amount) AS min_payment, MAX(p.amount) AS max_payment FROM payment_copy p JOIN staff s ON p.staff_id = s.staff_id WHERE p.payment_date >= DATE '2024-01-01' AND p.payment_date < DATE '2025-01-01' GROUP BY date_trunc('month', p.payment_date), s.store_id ORDER BY month, s.store_id; }}} За оптимизираната верзија се користи истата логика, но наместо payment_copy се користи партиционираната табела payment. || '''Clients''' || '''Threads''' || '''payment_copy latency''' || '''payment_copy stddev''' || '''payment_copy TPS''' || '''payment latency''' || '''payment stddev''' || '''payment TPS''' || '''Промена''' || || 10 || 4 || 2806.844 ms || 891.434 ms || 3.563 || 1121.703 ms || 536.035 ms || 8.915 || ~60.0% побрзо || || 30 || 4 || 10642.000 ms || 5393.351 ms || 2.819 || 3062.069 ms || 1034.027 ms || 9.797 || ~71.2% побрзо || || 50 || 4 || 24061.723 ms || 9254.155 ms || 2.078 || 5118.177 ms || 1494.030 ms || 9.769 || ~78.7% побрзо || Q3 има најдобри резултати бидејќи филтерот по payment_date директно го користи партиционирањето на табелата payment. Кај 50 клиенти латентноста се намалува од 24061.723 ms на 5118.177 ms, а TPS се зголемува од 2.078 на 9.769. Standard deviation е значително помала кај партиционираната табела. Кај 50 клиенти се намалува од 9254.155 ms на 1494.030 ms. Ова покажува дека партиционирањето според payment_date значително ја подобрува и брзината и стабилноста на извештајот. === Q4 - INSERT rental Овој тест мери внесување нови редови во табелата за изнајмувања. За benchmark редовите се користи посебен датум 2026-03-07 12:00:00, за да се разликуваат од оригиналните податоци. {{{ INSERT INTO rental_copy (rental_date, inventory_id, customer_id, staff_id) VALUES ( TIMESTAMP '2026-03-07 12:00:00', floor(random() * 50000 + 1)::int, floor(random() * 1000000 + 1)::int, floor(random() * 50 + 1)::int ); }}} За оптимизираната верзија се користи истата логика, но внесувањето се прави во партиционираната табела rental. || '''Clients''' || '''Threads''' || '''rental_copy latency''' || '''rental_copy stddev''' || '''rental_copy TPS''' || '''rental latency''' || '''rental stddev''' || '''rental TPS''' || '''Промена''' || || 10 || 4 || 2.750 ms || 0.818 ms || 3636.964 || 2.875 ms || 0.937 ms || 3478.295 || ~4.5% побавно || || 30 || 4 || 3.000 ms || 1.177 ms || 9999.631 || 3.340 ms || 1.557 ms || 8981.431 || ~11.3% побавно || || 50 || 4 || 7.099 ms || 2.297 ms || 7043.696 || 3.501 ms || 2.220 ms || 14281.463 || ~50.7% побрзо || Кај INSERT операциите резултатите се мешани. Кај 10 и 30 клиенти rental_copy има малку подобри резултати, бидејќи кај партиционираната табела PostgreSQL дополнително одредува во која партиција треба да се внесе редот. Кај 50 клиенти партиционираната табела покажува подобар резултат: латентноста се намалува од 7.099 ms на 3.501 ms, а TPS се зголемува од 7043.696 на 14281.463. === Q5 - UPDATE rental Овој тест мери ажурирање на изнајмувања. Се избира еден ред со benchmark датумот и со return_date IS NULL, па потоа се поставува return_date = now(). {{{ UPDATE rental_copy SET return_date = now() WHERE rental_id = ( SELECT rental_id FROM rental_copy WHERE rental_date = TIMESTAMP '2026-03-07 12:00:00' AND return_date IS NULL LIMIT 1 ); }}} За оптимизираната верзија се користи истата логика, но ажурирањето се прави врз партиционираната табела rental. || '''Clients''' || '''Threads''' || '''rental_copy latency''' || '''rental_copy stddev''' || '''rental_copy TPS''' || '''rental latency''' || '''rental stddev''' || '''rental TPS''' || '''Промена''' || || 10 || 4 || 704.821 ms || 61.336 ms || 14.188 || 7.093 ms || 3.997 ms || 1409.861 || ~99.0% побрзо || || 30 || 4 || 1923.308 ms || 457.842 ms || 15.598 || 26.970 ms || 16.112 ms || 1112.346 || ~98.6% побрзо || || 50 || 4 || 3124.384 ms || 700.922 ms || 16.003 || 17.475 ms || 13.475 ms || 2861.279 || ~99.4% побрзо || UPDATE операцијата покажува најголемо подобрување. Кај 10 клиенти латентноста се намалува од 704.821 ms на 7.093 ms, а кај 50 клиенти од 3124.384 ms на 17.475 ms. Standard deviation исто така значително се намалува. Кај 50 клиенти се намалува од 700.922 ms на 13.475 ms. Причината е што UPDATE условот користи конкретен rental_date, па кај партиционираната табела PostgreSQL ја ограничува операцијата на релевантната партиција. == Вкупно подобрување Партиционираните табели и индексите покажуваат најголемо подобрување кај прашалници кои користат временски филтер врз колоната по која е направено партиционирањето. Освен просечната латентност, во оваа анализа се зема предвид и standard deviation, која покажува колку е стабилно времето на извршување. Најголеми придобивки: * Q3 - Monthly Revenue: најголемо подобрување кај временски ограничените извештаи. Кај 50 клиенти латентноста се намалува од 24061.723 ms на 5118.177 ms, а standard deviation се намалува од 9254.155 ms на 1494.030 ms. Кај 50 клиенти латентноста се намалува од 24061.723 ms на 5118.177 ms, а standard deviation се намалува од 9254.155 ms на 1494.030 ms. * Q5 - UPDATE rental: најголемо подобрување кај write операциите. Кај 50 клиенти латентноста се намалува од 3124.384 ms на 17.475 ms, а standard deviation се намалува од 700.922 ms на 13.475 ms. * Q1 - Movie Recommendation: има подобрување кај сите нивоа на конкурентност, при што оптимизираната верзија има помала латентност и помала standard deviation. * Q2 - Popular Films: по новите мерења со standard deviation, партиционираната табела има подобри резултати кај сите тестирани нивоа на конкурентност. Мешани резултати: * Q4 - INSERT rental: резултатите се мешани. Кај 10 и 30 клиенти rental_copy е малку побрза, затоа што INSERT во партиционирана табела има дополнителен overhead за избор на партиција. Кај 50 клиенти партиционираната табела е подобра, со помала латентност и поголем TPS. Ова покажува дека оптимизацијата мора да се мери со повеќе метрики. Партиционирањето не е автоматско решение за сите операции, но е многу корисно кога прашалникот користи WHERE услов врз партициската колона, како rental_date или payment_date. Помалата standard deviation кај повеќето оптимизирани тестови покажува и постабилно, попредвидливо извршување. == Операции на читање * Q1 - Movie Recommendation: оптимизираната верзија има помала латентност, поголем TPS и помала standard deviation кај сите нивоа на конкурентност. * Q2 - Popular Films: по новите мерења, партиционираната табела има подобри резултати кај сите тестирани нивоа на конкурентност. Сепак, прашалникот содржи GROUP BY и ORDER BY, па агрегацијата и сортирањето остануваат значаен дел од трошокот. * Q3 - Monthly Revenue: најдобар пример каде партиционирањето директно го намалува бројот на редови што треба да се читаат, бидејќи филтерот користи payment_date, а табелата payment е партиционирана според истата колона. Кај операциите на читање, најдобри резултати се добиваат кога WHERE условот ја користи колоната по која е направено партиционирањето. Дополнително, помалата standard deviation кај оптимизираните верзии покажува дека извршувањето е постабилно и попредвидливо. == Операции на запишување * INSERT: резултатите се мешани. Кај 10 и 30 клиенти rental_copy е малку побрза, но кај 50 клиенти партиционираната табела има подобра латентност и повисок TPS. * UPDATE: има многу големо подобрување кај партиционираната табела, затоа што условот користи конкретна вредност за rental_date. Кај INSERT, партиционирањето може да додаде overhead затоа што PostgreSQL мора да одреди во која партиција треба да се внесе новиот ред. Кај UPDATE, партиционирањето е многу корисно кога условот ја користи партициската колона, бидејќи пребарувањето се ограничува на релевантната партиција наместо на целата табела. == Заклучок За ова специфично работно оптоварување: * Партиционирањето е многу корисно за временски извештаи, особено кај payment и rental. * Индексите значително помагаат кај прашалници со WHERE услови и JOIN операции врз често користени колони. * Q3 и Q5 покажуваат најголемо подобрување, затоа што директно ја користат колоната по која е направено партиционирањето. * Q1 и Q2 покажуваат подобрување кај SELECT прашалници кои користат временски филтри, но кај Q2 агрегацијата и сортирањето остануваат значаен дел од трошокот. * INSERT операциите треба да се мерат внимателно, бидејќи партиционирањето може да додаде overhead при внесување, особено при помал број клиенти. * Standard deviation е важна метрика затоа што покажува колку се стабилни перформансите. Кај повеќето оптимизирани тестови standard deviation е помала, што значи дека времето на извршување е попредвидливо. Најсоодветен пристап за оваа база е да се задржи партиционирањето по датум за големите трансакциски табели rental и payment, да се користат индекси само за најчестите филтри и спојувања, и редовно да се проверуваат резултатите со EXPLAIN ANALYZE и pgbench. = Мерење на перформанси по PostgreSQL tuning По иницијалното мерење на перформансите беше извршено дополнително подесување на PostgreSQL конфигурацијата. Целта беше базата подобро да ги користи достапните ресурси, особено меморијата, кеширањето и паралелното извршување. Тестирањето се извршува на машина со 32 GB RAM и Intel i9-9900K процесор. PostgreSQL работи во Docker/WSL околина, каде за време на тестирањето имаше достапно 16 GB RAM. Поради тоа, PostgreSQL tuning параметрите беа избрани според достапната меморија во Docker околината, а не според целосната физичка меморија на машината. Со `docker inspect` беше проверено дека контејнерот нема посебно зададено ограничување за CPU или меморија: {{{ docker inspect postgres-db --format='CPUs={{.HostConfig.NanoCpus}} Memory={{.HostConfig.Memory}}' CPUs=0 Memory=0 }}} == PostgreSQL tuning Оптимизацијата беше направена со `ALTER SYSTEM`, со што параметрите се запишуваат во PostgreSQL конфигурацијата: {{{ ALTER SYSTEM SET shared_buffers = '4GB'; ALTER SYSTEM SET effective_cache_size = '12GB'; ALTER SYSTEM SET work_mem = '64MB'; ALTER SYSTEM SET maintenance_work_mem = '1GB'; ALTER SYSTEM SET max_worker_processes = 16; ALTER SYSTEM SET max_parallel_workers = 8; ALTER SYSTEM SET max_parallel_workers_per_gather = 4; ALTER SYSTEM SET random_page_cost = 1.1; ALTER SYSTEM SET effective_io_concurrency = 200; }}} По поставувањето на параметрите, PostgreSQL контејнерот беше рестартиран: {{{ docker restart postgres-db }}} Потоа конфигурацијата беше проверена со следните `SHOW` команди: {{{ SHOW shared_buffers; SHOW effective_cache_size; SHOW work_mem; SHOW maintenance_work_mem; SHOW max_worker_processes; SHOW max_parallel_workers; SHOW max_parallel_workers_per_gather; SHOW random_page_cost; SHOW effective_io_concurrency; }}} Добиената активна конфигурација е: || '''Параметар''' || '''Вредност''' || '''Цел''' || || shared_buffers || 4GB || PostgreSQL кеш за табели и индекси. || || effective_cache_size || 12GB || Проценка за достапна кеш меморија за query planner-от. || || work_mem || 64MB || Меморија за sort, hash join, hash aggregate и GROUP BY операции. || || maintenance_work_mem || 1GB || Меморија за maintenance операции, на пример CREATE INDEX и VACUUM. || || max_worker_processes || 16 || Максимален број background worker процеси. || || max_parallel_workers || 8 || Вкупен број parallel workers за серверот. || || max_parallel_workers_per_gather || 4 || Максимален број parallel workers за еден прашалник. || || random_page_cost || 1.1 || Пониска цена за random I/O, посоодветна за SSD/NVMe и кеширани податоци. || || effective_io_concurrency || 200 || Подобро искористување на паралелни I/O операции. || Со оваа конфигурација повторно беа извршени истите `pgbench` тестови. == Детални резултати по PostgreSQL tuning === Q1 - Movie Recommendation Прашалникот прави препорака на филмови за конкретен корисник. Се користат претходните изнајмувања, категориите, рејтинзите и популарноста на филмовите во 2024 година. || '''Clients''' || '''Threads''' || '''rental_copy latency''' || '''rental_copy stddev''' || '''rental_copy TPS''' || '''rental latency''' || '''rental stddev''' || '''rental TPS''' || '''Промена''' || || 10 || 2 || 1920.007 ms || 724.511 ms || 5.208 || 833.150 ms || 433.224 ms || 12.003 || ~56.6% побрзо || || 20 || 4 || 3553.036 ms || 1122.492 ms || 5.629 || 2136.662 ms || 1000.752 ms || 9.360 || ~39.9% побрзо || || 50 || 4 || 8547.274 ms || 1838.716 ms || 5.850 || 5106.524 ms || 1606.435 ms || 9.791 || ~40.3% побрзо || По tuning, партиционираната табела `rental` покажува значително подобри резултати од `rental_copy`. Латентноста е помала кај сите нивоа на конкурентност, TPS е повисок, а standard deviation е помала. Ова покажува дека оптимизираната структура дава побрзо и постабилно извршување. === Q2 - Popular Films 2024 Прашалникот ги пресметува најизнајмуваните филмови во 2024 година. Содржи филтер по `rental_date`, JOIN со `inventory` и `film`, групирање по филм и сортирање според бројот на изнајмувања. || '''Clients''' || '''Threads''' || '''rental_copy latency''' || '''rental_copy stddev''' || '''rental_copy TPS''' || '''rental latency''' || '''rental stddev''' || '''rental TPS''' || '''Промена''' || || 10 || 4 || 1560.813 ms || 883.089 ms || 6.407 || 1321.393 ms || 674.246 ms || 7.568 || ~15.3% побрзо || || 20 || 4 || 3136.978 ms || 1464.866 ms || 6.376 || 2730.179 ms || 1229.865 ms || 7.326 || ~13.0% побрзо || || 30 || 4 || 5259.732 ms || 2139.302 ms || 5.704 || 3950.966 ms || 1442.761 ms || 7.593 || ~24.9% побрзо || || 50 || 4 || 9015.934 ms || 2895.372 ms || 5.546 || 6633.659 ms || 2024.828 ms || 7.537 || ~26.4% побрзо || По tuning, партиционираната табела има подобри резултати кај сите тестирани нивоа на конкурентност. Кај 10 клиенти латентноста се намалува за околу 15.3%, а кај 50 клиенти за околу 26.4%. TPS е повисок кај партиционираната табела во сите мерења, а standard deviation е помала. Ова покажува дека оптимизираната верзија има постабилно време на извршување. PostgreSQL tuning помага преку поголем `work_mem` за агрегација и сортирање, додека партиционирањето помага бидејќи прашалникот чита податоци само за 2024 година. === Q3 - Monthly Revenue Прашалникот пресметува месечен приход по продавница за 2024 година. Се користи филтер по `payment_date`, JOIN со `staff` и агрегации како `COUNT`, `SUM`, `AVG`, `MIN` и `MAX`. || '''Clients''' || '''Threads''' || '''payment_copy latency''' || '''payment_copy stddev''' || '''payment_copy TPS''' || '''payment latency''' || '''payment stddev''' || '''payment TPS''' || '''Промена''' || || 10 || 4 || 2681.628 ms || 952.943 ms || 3.729 || 1104.610 ms || 593.580 ms || 9.053 || ~58.8% побрзо || || 30 || 4 || 6844.099 ms || 1907.879 ms || 4.383 || 3152.069 ms || 1234.209 ms || 9.518 || ~53.9% побрзо || || 50 || 4 || 11372.246 ms || 2677.587 ms || 4.397 || 5309.611 ms || 1701.580 ms || 9.417 || ~53.3% побрзо || Q3 покажува големо подобрување бидејќи прашалникот филтрира по `payment_date`, а табелата `payment` е партиционирана според истата колона. PostgreSQL може да ја ограничи обработката на релевантната партиција за 2024 година. TPS е повеќе од двојно поголем кај партиционираната табела, а standard deviation е помала во сите тестови. Ова покажува побрзо и попредвидливо извршување. === Q4 - INSERT rental Овој тест мери внесување нови редови во табелата за изнајмувања. За benchmark редовите се користи датумот `2026-03-07 12:00:00`, за да можат лесно да се издвојат и избришат по тестирањето. || '''Clients''' || '''Threads''' || '''rental_copy latency''' || '''rental_copy stddev''' || '''rental_copy TPS''' || '''rental latency''' || '''rental stddev''' || '''rental TPS''' || '''Промена''' || || 10 || 4 || 2.752 ms || 0.627 ms || 3633.816 || 3.026 ms || 2.168 ms || 3304.381 || ~10.0% побавно || || 30 || 4 || 2.978 ms || 1.276 ms || 10072.768 || 3.442 ms || 1.440 ms || 8716.851 || ~15.6% побавно || || 50 || 4 || 3.114 ms || 1.740 ms || 16058.633 || 3.588 ms || 2.118 ms || 13935.611 || ~15.2% побавно || Кај INSERT операциите, партиционираната табела е малку побавна во сите три мерења. Ова е очекувано бидејќи при INSERT во партиционирана табела PostgreSQL мора да одреди во која партиција припаѓа новиот ред и да ги ажурира индексите на соодветната партиција. И покрај тоа, разликата е мала во апсолутна вредност, бидејќи латентноста и кај двете табели останува во опсег од неколку милисекунди. Ова покажува дека партиционирањето не мора секогаш да го забрза INSERT. === Q5 - UPDATE rental Овој тест мери ажурирање на редови со `rental_date = TIMESTAMP '2026-03-07 12:00:00'` и `return_date IS NULL`. || '''Clients''' || '''Threads''' || '''rental_copy latency''' || '''rental_copy stddev''' || '''rental_copy TPS''' || '''rental latency''' || '''rental stddev''' || '''rental TPS''' || '''Промена''' || || 10 || 4 || 697.000 ms || 343.262 ms || 14.347 || 6.907 ms || 3.537 ms || 1447.849 || ~99.0% побрзо || || 30 || 4 || 1762.767 ms || 393.804 ms || 17.019 || 12.705 ms || 7.407 ms || 2361.325 || ~99.3% побрзо || || 50 || 4 || 2926.856 ms || 626.986 ms || 17.083 || 16.336 ms || 10.520 ms || 3060.774 || ~99.4% побрзо || UPDATE операцијата покажува најголемо подобрување. Кај 10 клиенти латентноста се намалува од 697.000 ms на 6.907 ms, а кај 50 клиенти од 2926.856 ms на 16.336 ms. TPS е многу поголем кај партиционираната табела, а standard deviation е значително помала. Причината е тоа што условот користи конкретен `rental_date`. Бидејќи `rental` е партиционирана според `rental_date`, PostgreSQL може да ја ограничи операцијата на релевантната партиција наместо да пребарува низ целата табела. == Вкупна анализа По PostgreSQL tuning, најголеми придобивки има кај прашалниците што користат временски филтер врз колоната по која е направено партиционирањето. Најголеми подобрувања: * Q5 - UPDATE rental: околу 99% намалување на латентноста кај партиционираната табела. * Q3 - Monthly Revenue: околу 53-59% намалување на латентноста кај партиционираната табела. * Q1 - Movie Recommendation: околу 40-57% подобрување, зависно од бројот на клиенти. * Q2 - Popular Films 2024: околу 13-26% подобрување, со помала standard deviation. Мешан резултат има кај Q4 - INSERT rental. Партиционираната табела е околу 10-16% побавна, бидејќи INSERT во партиционирана табела има дополнителен overhead за избор на партиција и ажурирање на индексите. == Заклучок PostgreSQL tuning овозможува подобро користење на меморијата, кешот и процесорските ресурси. Зголемувањето на `work_mem`, `effective_cache_size` и parallel worker параметрите најмногу помага кај прашалници со JOIN, GROUP BY, ORDER BY и агрегации. Партиционирањето и индексите остануваат најважни кај операции што користат временски филтер по `rental_date` или `payment_date`. Најјасен пример е Q5, каде UPDATE операцијата е над 99% побрза кај партиционираната табела.