Changes between Version 8 and Version 9 of QueryOptimization


Ignore:
Timestamp:
05/12/26 15:11:47 (2 weeks ago)
Author:
231017
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • QueryOptimization

    v8 v9  
    326326Исто така вреди да се напомене дека во апликацискиот код ќе треба да имплементираме логика за повремено ажурирање на овие погледи, користејќи `REFRESH MATERIALIZED VIEW`, и дека еден ваков refresh трае ~45 секунди.
    327327
    328 === 4. Анализа на поглед 4, рангирање на артистите по слушања (популарност) во изминатите 30 дена ===
    329 
    330 - Доколку сакаме да видиме како одреден артист се рангира во споредба со остнатите артисти, извршуваме:
    331 
    332   [[Image(View4_1.png, 800px)]]
    333 
    334 - Време потребно за пребарување:
    335 
    336   [[Image(View4_2.png, 800px)]]
    337 
    338   [[Image(View4_3.png, 800px)]]
    339 
    340   [[Image(View4_4.png, 800px)]]
    341 
    342 - **~5-6sec**.  Бавната операција е секвенцијално пребарување на Song_streams табелата што би можеле да го оптимизираме со индекс:
    343 
    344   [[Image(View4_5.png, 800px)]]
    345 
    346 - Време на извршување **со индекс**:
    347 
    348   [[Image(View4_6.png, 800px)]]
    349 
    350   [[Image(View4_7.png, 800px)]]
    351 
    352 - **~2sec**. Со индекс добивме ~ 57% побрзо извршување.
    353 
    354 - Време потребно за внес на запис во Song_streams **без индекс**:
    355 
    356   [[Image(View4_8.png, 800px)]]
    357 
    358   [[Image(View4_9.png, 800px)]]
    359 
    360 - **0.2ms**
    361 
    362 - Време потребно за внес на запис во Song_streams со индекс:
    363 
    364   [[Image(View4_10.png, 800px)]]
    365 
    366 - **~3ms**
    367 
    368 - Време потребно за ажурирање запис во Song_streams **без индекс**:
    369 
    370   [[Image(View4_11.png, 800px)]]
    371  
    372   [[Image(View4_12.png, 800px)]]
    373 
    374 - **~0.7ms**
    375 
    376 - Време потребно за ажурирање запис во Song_streams **со индекс**:
    377  
    378   [[Image(View4_13.png, 800px)]]
    379 
    380 - **~0.2ms**
    381 
     328=== 4. Анализа на поглед 4, број на слушања (популарност) на артисте за изминатите 30 дена
     329
     330Прашалник кој ќе го тестираме:
     331
     332{{{
     333SELECT * FROM artist_popularity_last_30_days WHERE artist_display_name='Rush';
     334}}}
     335
     336==== Време на извршување без индекси:
     337
     338**5295.544 ms**
     339
     340{{{
     341 Subquery Scan on artist_popularity_last_30_days  (cost=258658.87..261658.85 rows=500 width=60) (actual time=5248.277..5288.441 rows=41 loops=1)
     342   Filter: ((artist_popularity_last_30_days.artist_display_name)::text = 'Rush'::text)
     343   Rows Removed by Filter: 99959
     344   ->  WindowAgg  (cost=258658.87..260408.85 rows=100000 width=60) (actual time=5247.481..5281.467 rows=100000 loops=1)
     345         ->  Sort  (cost=258658.85..258908.85 rows=100000 width=52) (actual time=5247.444..5253.777 rows=100000 loops=1)
     346               Sort Key: artist_listens.total_listens DESC
     347               Sort Method: quicksort  Memory: 7706kB
     348               ->  Subquery Scan on artist_listens  (cost=249104.03..250354.03 rows=100000 width=52) (actual time=5163.853..5210.492 rows=100000 loops=1)
     349                     ->  HashAggregate  (cost=249104.03..250354.03 rows=100000 width=52) (actual time=5163.847..5200.274 rows=100000 loops=1)
     350                           Group Key: a.id
     351                           Batches: 1  Memory Usage: 22545kB
     352                           ->  Hash Left Join  (cost=173161.35..239347.87 rows=1951232 width=28) (actual time=3172.252..4602.821 rows=1953805 loops=1)
     353                                 Hash Cond: (s.id = sc.song_id)
     354                                 ->  Hash Right Join  (cost=3618.00..64682.53 rows=1951232 width=28) (actual time=123.141..1016.733 rows=1953805 loops=1)
     355                                       Hash Cond: (s.owner_artist_id = a.id)
     356                                       ->  Seq Scan on songs s  (cost=0.00..55942.32 rows=1951232 width=16) (actual time=70.738..304.609 rows=1951232 loops=1)
     357                                       ->  Hash  (cost=2368.00..2368.00 rows=100000 width=20) (actual time=52.166..52.167 rows=100000 loops=1)
     358                                             Buckets: 131072  Batches: 1  Memory Usage: 6157kB
     359                                             ->  Seq Scan on artists a  (cost=0.00..2368.00 rows=100000 width=20) (actual time=21.265..34.097 rows=100000 loops=1)
     360                                 ->  Hash  (cost=167349.12..167349.12 rows=175538 width=16) (actual time=3048.716..3048.831 rows=304092 loops=1)
     361                                       Buckets: 524288 (originally 262144)  Batches: 1 (originally 1)  Memory Usage: 18351kB
     362                                       ->  Subquery Scan on sc  (cost=163838.36..167349.12 rows=175538 width=16) (actual time=2861.695..2967.031 rows=304092 loops=1)
     363                                             ->  Finalize HashAggregate  (cost=163838.36..165593.74 rows=175538 width=16) (actual time=2861.688..2940.091 rows=304092 loops=1)
     364                                                   Group Key: ss.song_id
     365                                                   Batches: 1  Memory Usage: 36881kB
     366                                                   ->  Gather  (cost=88357.02..160327.60 rows=702152 width=16) (actual time=2650.692..2751.352 rows=304092 loops=1)
     367                                                         Workers Planned: 4
     368                                                         Workers Launched: 0
     369                                                         ->  Partial HashAggregate  (cost=87357.02..89112.40 rows=175538 width=16) (actual time=2650.252..2729.313 rows=304092 loops=1)
     370                                                               Group Key: ss.song_id
     371                                                               Batches: 1  Memory Usage: 36881kB
     372                                                               ->  Parallel Seq Scan on song_streams ss  (cost=0.00..86108.61 rows=249682 width=8) (actual time=0.039..2307.530 rows=996439 loops=1)
     373                                                                     Filter: (streamed_at >= (CURRENT_TIMESTAMP - '30 days'::interval))
     374                                                                     Rows Removed by Filter: 5779244
     375 Planning Time: 0.601 ms
     376 JIT:
     377   Functions: 38
     378 "  Options: Inlining false, Optimization false, Expressions true, Deforming true"
     379 "  Timing: Generation 2.191 ms (Deform 0.875 ms), Inlining 0.000 ms, Optimization 0.746 ms, Emission 20.211 ms, Total 23.149 ms"
     380 Execution Time: 5295.544 ms
     381}}}
     382
     383Најбавните делови се секвенцијално скенирање на табелите {{{song_streams}}} и {{{songs}}}, што можеме да го оптимизираме со индекс:
     384
     385{{{
     386CREATE INDEX idx_song_streams_streamed_at_song_id ON song_streams(streamed_at, song_id);
     387CREATE INDEX idx_songs_owner_artist_id ON songs(owner_artist_id);
     388}}}
     389
     390==== Време на извршување со индекси:
     391
     392**2923.180 ms**
     393
     394{{{
     395WindowAgg  (cost=132657.36..134407.34 rows=100000 width=60) (actual time=2878.456..2912.811 rows=100000 loops=1)
     396  ->  Sort  (cost=132657.34..132907.34 rows=100000 width=52) (actual time=2878.421..2884.685 rows=100000 loops=1)
     397        Sort Key: artist_listens.total_listens DESC
     398        Sort Method: quicksort  Memory: 7706kB
     399        ->  Subquery Scan on artist_listens  (cost=123102.52..124352.52 rows=100000 width=52) (actual time=2795.069..2840.462 rows=100000 loops=1)
     400              ->  HashAggregate  (cost=123102.52..124352.52 rows=100000 width=52) (actual time=2795.063..2830.225 rows=100000 loops=1)
     401                    Group Key: a.id
     402                    Batches: 1  Memory Usage: 22545kB
     403                    ->  Hash Left Join  (cost=47159.84..113346.36 rows=1951232 width=28) (actual time=826.776..2239.576 rows=1953805 loops=1)
     404                          Hash Cond: (s.id = sc.song_id)
     405                          ->  Hash Right Join  (cost=3618.00..64682.53 rows=1951232 width=28) (actual time=118.783..1004.286 rows=1953805 loops=1)
     406                                Hash Cond: (s.owner_artist_id = a.id)
     407                                ->  Seq Scan on songs s  (cost=0.00..55942.32 rows=1951232 width=16) (actual time=69.772..303.956 rows=1951232 loops=1)
     408                                ->  Hash  (cost=2368.00..2368.00 rows=100000 width=20) (actual time=48.780..48.781 rows=100000 loops=1)
     409                                      Buckets: 131072  Batches: 1  Memory Usage: 6157kB
     410                                      ->  Seq Scan on artists a  (cost=0.00..2368.00 rows=100000 width=20) (actual time=17.634..30.840 rows=100000 loops=1)
     411                          ->  Hash  (cost=41347.61..41347.61 rows=175538 width=16) (actual time=707.572..707.574 rows=304102 loops=1)
     412                                Buckets: 524288 (originally 262144)  Batches: 1 (originally 1)  Memory Usage: 18351kB
     413                                ->  Subquery Scan on sc  (cost=37836.85..41347.61 rows=175538 width=16) (actual time=533.395..631.097 rows=304102 loops=1)
     414                                      ->  HashAggregate  (cost=37836.85..39592.23 rows=175538 width=16) (actual time=533.387..597.876 rows=304102 loops=1)
     415                                            Group Key: ss.song_id
     416                                            Batches: 1  Memory Usage: 36881kB
     417                                            ->  Index Only Scan using idx_song_streams_streamed_at_song_id on song_streams ss  (cost=0.44..32842.98 rows=998774 width=8) (actual time=0.057..245.680 rows=996484 loops=1)
     418                                                  Index Cond: (streamed_at >= (CURRENT_TIMESTAMP - '30 days'::interval))
     419                                                  Heap Fetches: 0
     420Planning Time: 0.573 ms
     421JIT:
     422  Functions: 32
     423"  Options: Inlining false, Optimization false, Expressions true, Deforming true"
     424"  Timing: Generation 2.147 ms (Deform 0.709 ms), Inlining 0.000 ms, Optimization 0.652 ms, Emission 16.640 ms, Total 19.439 ms"
     425Execution Time: 2923.180 ms
     426}}}
     427
     428Сега планерот го користи креираниот индекс за табелата {{{song_streams}}}, но сепак табелата {{{songs}}} треба секвенцијално да се скенира за да се пресмета статистиката за артистите. Дополнителна оптимизација правиме со материјализиран поглед:
     429
     430{{{
     431CREATE MATERIALIZED VIEW artist_popularity_last_30_days_mv AS
     432WITH streams_count AS (
     433    SELECT ss.song_id, COUNT(*) AS cnt
     434    FROM song_streams ss
     435    WHERE ss.streamed_at >= CURRENT_TIMESTAMP - INTERVAL '30 days'
     436    GROUP BY ss.song_id
     437),
     438artist_listens AS (
     439    SELECT
     440        a.id AS artist_id,
     441        a.display_name AS artist_display_name,
     442        COALESCE(SUM(sc.cnt), 0) AS total_listens
     443    FROM artists a
     444    LEFT JOIN songs s ON s.owner_artist_id = a.id
     445    LEFT JOIN streams_count sc ON sc.song_id = s.id
     446    GROUP BY a.id, a.display_name
     447)
     448SELECT
     449    ROW_NUMBER() OVER (ORDER BY total_listens DESC) AS rank,
     450    artist_id,
     451    artist_display_name,
     452    total_listens
     453FROM artist_listens;
     454
     455}}}
     456
     457==== Време за извршување на прашалникот по додавање на материјализиран поглед
     458
     459{{{
     460Seq Scan on artist_popularity_last_30_days_mv  (cost=0.00..2082.00 rows=2 width=31) (actual time=0.210..9.704 rows=41 loops=1)
     461  Filter: ((artist_display_name)::text = 'Rush'::text)
     462  Rows Removed by Filter: 99959
     463Planning Time: 0.094 ms
     464Execution Time: 9.731 ms
     465}}}
     466
     467Со материјализиран поглед добиваме <10 ms за читање.
     468
     469=== 5. Анализа на поглед 5, број на слушања (популарност) на песните за изминатите 30 дена
     470
     471Прашалник кој ќе го тестираме:
     472
     473{{{
     474SELECT * FROM most_popular_songs_last_30_days WHERE rank=15;
     475}}}
     476
     477==== Време за извршување со креираниот индекс {{{idx_song_streams_streamed_at_song_id}}}
     478
     479**1682.017 ms**
     480
     481{{{
     482Subquery Scan on most_popular_songs_last_30_days  (cost=96713.63..122558.33 rows=878 width=96) (actual time=1471.660..1677.911 rows=1 loops=1)
     483  Filter: (most_popular_songs_last_30_days.rank = 17)
     484  Rows Removed by Filter: 16
     485  ->  WindowAgg  (cost=96713.63..120364.14 rows=175535 width=96) (actual time=1471.640..1677.902 rows=17 loops=1)
     486        Run Condition: (row_number() OVER (?) <= 17)
     487        ->  Gather Merge  (cost=96713.50..117731.12 rows=175535 width=88) (actual time=1471.591..1677.843 rows=18 loops=1)
     488              Workers Planned: 4
     489              Workers Launched: 4
     490              ->  Sort  (cost=95713.44..95823.15 rows=43884 width=88) (actual time=1433.450..1433.565 rows=564 loops=5)
     491                    Sort Key: sc.total_streams DESC
     492                    Sort Method: quicksort  Memory: 9470kB
     493                    Worker 0:  Sort Method: quicksort  Memory: 9145kB
     494                    Worker 1:  Sort Method: quicksort  Memory: 2511kB
     495                    Worker 2:  Sort Method: quicksort  Memory: 2431kB
     496                    Worker 3:  Sort Method: quicksort  Memory: 9520kB
     497                    ->  Parallel Hash Join  (cost=49328.85..92329.67 rows=43884 width=88) (actual time=1114.045..1407.397 rows=60789 loops=5)
     498                          Hash Cond: (s.owner_artist_id = a.id)
     499                          ->  Hash Left Join  (cost=46637.31..89522.94 rows=43884 width=84) (actual time=1076.395..1343.191 rows=60789 loops=5)
     500                                Hash Cond: (s.published_by_label_admin_id = la.id)
     501                                ->  Hash Join  (cost=43501.50..86090.08 rows=43884 width=48) (actual time=1071.308..1327.862 rows=60789 loops=5)
     502                                      Hash Cond: (s.id = sc.song_id)
     503                                      ->  Parallel Seq Scan on songs s  (cost=0.00..41308.08 rows=487808 width=40) (actual time=0.092..135.322 rows=390246 loops=5)
     504                                      ->  Hash  (cost=41307.31..41307.31 rows=175535 width=16) (actual time=1069.687..1069.689 rows=303945 loops=5)
     505                                            Buckets: 524288 (originally 262144)  Batches: 1 (originally 1)  Memory Usage: 18344kB
     506                                            ->  Subquery Scan on sc  (cost=37796.61..41307.31 rows=175535 width=16) (actual time=837.380..966.924 rows=303945 loops=5)
     507                                                  ->  HashAggregate  (cost=37796.61..39551.96 rows=175535 width=16) (actual time=837.372..937.795 rows=303945 loops=5)
     508                                                        Group Key: song_streams.song_id
     509                                                        Batches: 1  Memory Usage: 36881kB
     510                                                        Worker 0:  Batches: 1  Memory Usage: 36881kB
     511                                                        Worker 1:  Batches: 1  Memory Usage: 36881kB
     512                                                        Worker 2:  Batches: 1  Memory Usage: 36881kB
     513                                                        Worker 3:  Batches: 1  Memory Usage: 36881kB
     514                                                        ->  Index Only Scan using idx_song_streams_streamed_at_song_id on song_streams  (cost=0.44..32809.02 rows=997519 width=8) (actual time=0.137..407.430 rows=995226 loops=5)
     515                                                              Index Cond: (streamed_at >= (CURRENT_TIMESTAMP - '30 days'::interval))
     516                                                              Heap Fetches: 95
     517                                ->  Hash  (cost=3131.12..3131.12 rows=375 width=48) (actual time=4.957..4.961 rows=375 loops=5)
     518                                      Buckets: 1024  Batches: 1  Memory Usage: 38kB
     519                                      ->  Nested Loop Left Join  (cost=13.86..3131.12 rows=375 width=48) (actual time=0.389..4.675 rows=375 loops=5)
     520                                            ->  Hash Left Join  (cost=13.44..21.18 rows=375 width=39) (actual time=0.317..0.558 rows=375 loops=5)
     521                                                  Hash Cond: (la.label_id = l.id)
     522                                                  ->  Seq Scan on label_admins la  (cost=0.00..6.75 rows=375 width=24) (actual time=0.068..0.157 rows=375 loops=5)
     523                                                  ->  Hash  (cost=8.75..8.75 rows=375 width=31) (actual time=0.214..0.215 rows=375 loops=5)
     524                                                        Buckets: 1024  Batches: 1  Memory Usage: 33kB
     525                                                        ->  Seq Scan on labels l  (cost=0.00..8.75 rows=375 width=31) (actual time=0.051..0.109 rows=375 loops=5)
     526                                            ->  Index Scan using users_pkey on users u  (cost=0.42..8.29 rows=1 width=25) (actual time=0.010..0.010 rows=1 loops=1875)
     527                                                  Index Cond: (id = la.user_id)
     528                          ->  Parallel Hash  (cost=1956.24..1956.24 rows=58824 width=20) (actual time=37.138..37.139 rows=20000 loops=5)
     529                                Buckets: 131072  Batches: 1  Memory Usage: 6528kB
     530                                ->  Parallel Seq Scan on artists a  (cost=0.00..1956.24 rows=58824 width=20) (actual time=27.866..30.351 rows=20000 loops=5)
     531Planning Time: 1.492 ms
     532JIT:
     533  Functions: 235
     534"  Options: Inlining false, Optimization false, Expressions true, Deforming true"
     535"  Timing: Generation 14.075 ms (Deform 6.062 ms), Inlining 0.000 ms, Optimization 5.950 ms, Emission 133.686 ms, Total 153.711 ms"
     536Execution Time: 1682.017 ms
     537}}}
     538
     539За дополнителна оптимизација креираме материјализиран поглед:
     540
     541{{{
     542CREATE MATERIALIZED VIEW most_popular_songs_last_30_days_mv AS
     543WITH stream_counts AS (
     544    SELECT
     545        song_id,
     546        COUNT(*) AS total_streams
     547    FROM song_streams
     548    WHERE streamed_at >= CURRENT_TIMESTAMP - INTERVAL '30 days'
     549    GROUP BY song_id
     550)
     551SELECT
     552    ROW_NUMBER() OVER (ORDER BY sc.total_streams DESC) AS rank,
     553    s.id AS song_id,
     554    s.title AS song_title,
     555    a.display_name AS artist_display_name,
     556    s.visibility AS song_visibility,
     557    u.username AS label_admin_username,
     558    l.name AS label_name,
     559    sc.total_streams
     560FROM stream_counts sc
     561JOIN songs s ON s.id = sc.song_id
     562JOIN artists a ON s.owner_artist_id = a.id
     563LEFT JOIN label_admins la ON s.published_by_label_admin_id = la.id
     564LEFT JOIN labels l ON l.id = la.label_id
     565LEFT JOIN users u ON u.id = la.user_id;
     566}}}
     567
     568==== Време за извршување на прашалникот по додавање на материјализиран поглед
     569
     570{{{
     571Gather  (cost=1000.00..6167.16 rows=1 width=96) (actual time=0.381..671.251 rows=1 loops=1)
     572  Workers Planned: 2
     573  Workers Launched: 2
     574  ->  Parallel Seq Scan on most_popular_songs_last_30_days_mv  (cost=0.00..5167.06 rows=1 width=96) (actual time=417.275..638.156 rows=0 loops=3)
     575        Filter: (rank = 17)
     576        Rows Removed by Filter: 101315
     577Planning Time: 0.218 ms
     578Execution Time: 671.277 ms
     579}}}
     580
     581Со материјализиран поглед добиваме <1s време на читање.
     582
     583
     584=== 6. Анализа на поглед 6, детален преглед за артистите групирани по издавачка куќа на која припаѓаат
     585
     586Го тестираме прашалникот:
     587
     588{{{ SELECT * FROM label_artists_info WHERE label_name='Piercing Abyss Records';}}}
     589
     590
     591==== Време за извршување без индекси
     592
     593**3197.076 ms**
     594
     595{{{
     596Subquery Scan on label_artists_info  (cost=48955.19..49185.03 rows=1561 width=51) (actual time=3166.576..3196.926 rows=81 loops=1)
     597  ->  GroupAggregate  (cost=48955.19..49169.42 rows=1561 width=59) (actual time=3166.575..3196.914 rows=81 loops=1)
     598        Group Key: a.id
     599        ->  Gather Merge  (cost=48955.19..49142.10 rows=1561 width=59) (actual time=3166.542..3196.531 rows=1660 loops=1)
     600              Workers Planned: 4
     601              Workers Launched: 4
     602              ->  Sort  (cost=47955.14..47956.11 rows=390 width=59) (actual time=2548.301..2548.327 rows=332 loops=5)
     603"                    Sort Key: a.id, s.id"
     604                    Sort Method: quicksort  Memory: 68kB
     605                    Worker 0:  Sort Method: quicksort  Memory: 35kB
     606                    Worker 1:  Sort Method: quicksort  Memory: 39kB
     607                    Worker 2:  Sort Method: quicksort  Memory: 44kB
     608                    Worker 3:  Sort Method: quicksort  Memory: 60kB
     609                    ->  Nested Loop Left Join  (cost=3303.17..47938.35 rows=390 width=59) (actual time=254.314..2547.203 rows=332 loops=5)
     610                          ->  Hash Join  (cost=3302.88..47724.69 rows=390 width=59) (actual time=202.108..1249.756 rows=328 loops=5)
     611                                Hash Cond: (a.id = al.artist_id)
     612                                ->  Parallel Hash Right Join  (cost=2691.54..45280.17 rows=487808 width=36) (actual time=42.618..1060.686 rows=390761 loops=5)
     613                                      Hash Cond: (s.owner_artist_id = a.id)
     614                                      ->  Parallel Seq Scan on songs s  (cost=0.00..41308.08 rows=487808 width=16) (actual time=0.371..871.469 rows=390246 loops=5)
     615                                      ->  Parallel Hash  (cost=1956.24..1956.24 rows=58824 width=28) (actual time=41.753..41.754 rows=20000 loops=5)
     616                                            Buckets: 131072  Batches: 1  Memory Usage: 7328kB
     617                                            ->  Parallel Seq Scan on artists a  (cost=0.00..1956.24 rows=58824 width=28) (actual time=3.800..28.812 rows=20000 loops=5)
     618                                ->  Hash  (cost=610.34..610.34 rows=80 width=31) (actual time=152.360..152.362 rows=81 loops=5)
     619                                      Buckets: 1024  Batches: 1  Memory Usage: 14kB
     620                                      ->  Hash Join  (cost=9.70..610.34 rows=80 width=31) (actual time=51.681..152.281 rows=81 loops=5)
     621                                            Hash Cond: (al.label_id = l.id)
     622                                            ->  Seq Scan on artist_labels al  (cost=0.00..521.00 rows=30000 width=16) (actual time=11.763..115.238 rows=30000 loops=5)
     623                                            ->  Hash  (cost=9.69..9.69 rows=1 width=31) (actual time=33.047..33.048 rows=1 loops=5)
     624                                                  Buckets: 1024  Batches: 1  Memory Usage: 9kB
     625                                                  ->  Seq Scan on labels l  (cost=0.00..9.69 rows=1 width=31) (actual time=32.998..33.038 rows=1 loops=5)
     626                                                        Filter: ((name)::text = 'Piercing Abyss Records'::text)
     627                                                        Rows Removed by Filter: 374
     628                          ->  Index Scan using idx_follows_followed_user_id on follows f  (cost=0.29..0.47 rows=8 width=16) (actual time=3.764..3.959 rows=1 loops=1638)
     629                                Index Cond: (followed_user_id = a.user_id)
     630Planning Time: 1776.191 ms
     631Execution Time: 3197.076 ms
     632}}}
     633
     634За да го оптимизираме секвенцијалното скенирање на табелите {{{songs}}} и {{{artist_labels}}}, ги креираме индексите:
     635
     636{{{
     637CREATE INDEX idx_songs_owner_artist_id ON songs(owner_artist_id);
     638CREATE INDEX idx_artist_labels_label_id_artist_id ON artist_labels(label_id, artist_id);
     639}}}
     640
     641==== Време за извршување со индекси
     642
     643**5.213 ms**
     644
     645{{{
     646Subquery Scan on label_artists_info  (cost=571.17..618.00 rows=1561 width=51) (actual time=4.634..5.127 rows=81 loops=1)
     647  ->  GroupAggregate  (cost=571.17..602.39 rows=1561 width=59) (actual time=4.633..5.116 rows=81 loops=1)
     648        Group Key: a.id
     649        ->  Sort  (cost=571.17..575.07 rows=1561 width=59) (actual time=4.614..4.708 rows=1660 loops=1)
     650"              Sort Key: a.id, s.id"
     651              Sort Method: quicksort  Memory: 171kB
     652              ->  Nested Loop Left Join  (cost=6.04..488.37 rows=1561 width=59) (actual time=0.125..3.388 rows=1660 loops=1)
     653                    ->  Nested Loop Left Join  (cost=5.62..274.33 rows=80 width=51) (actual time=0.115..0.973 rows=83 loops=1)
     654                          ->  Nested Loop  (cost=5.32..230.51 rows=80 width=51) (actual time=0.105..0.685 rows=81 loops=1)
     655                                ->  Nested Loop  (cost=4.91..175.24 rows=80 width=31) (actual time=0.092..0.265 rows=81 loops=1)
     656                                      ->  Seq Scan on labels l  (cost=0.00..9.69 rows=1 width=31) (actual time=0.051..0.075 rows=1 loops=1)
     657                                            Filter: ((name)::text = 'Piercing Abyss Records'::text)
     658                                            Rows Removed by Filter: 374
     659                                      ->  Bitmap Heap Scan on artist_labels al  (cost=4.91..164.75 rows=80 width=16) (actual time=0.038..0.174 rows=81 loops=1)
     660                                            Recheck Cond: (l.id = label_id)
     661                                            Heap Blocks: exact=72
     662                                            ->  Bitmap Index Scan on idx_artist_labels_label_id_artist_id  (cost=0.00..4.89 rows=80 width=0) (actual time=0.019..0.019 rows=81 loops=1)
     663                                                  Index Cond: (label_id = l.id)
     664                                ->  Index Scan using artists_pkey on artists a  (cost=0.42..0.69 rows=1 width=28) (actual time=0.005..0.005 rows=1 loops=81)
     665                                      Index Cond: (id = al.artist_id)
     666                          ->  Index Scan using idx_follows_followed_user_id on follows f  (cost=0.29..0.47 rows=8 width=16) (actual time=0.003..0.003 rows=1 loops=81)
     667                                Index Cond: (followed_user_id = a.user_id)
     668                    ->  Index Scan using idx_songs_owner_artist_id on songs s  (cost=0.43..2.42 rows=26 width=16) (actual time=0.004..0.026 rows=20 loops=83)
     669                          Index Cond: (owner_artist_id = a.id)
     670Planning Time: 1.229 ms
     671Execution Time: 5.213 ms
     672}}}
     673
     674Планерот го користи и претходно креираниот индекс {{{idx_follows_followed_user_id}}}. Индексите го забрзаа извршувањето за речиси 100%, па заклучуваме дека нема потреба од дополнителна оптимизација.
     675
     676
     677=== 7. Анализа на поглед 7, детални информации за секоја песна
     678
     679Прашалник кој го тестираме:
     680
     681{{{
     682SELECT * FROM songs_details WHERE title='Harmony';
     683}}}
     684
     685==== Време за извршување без индекси
     686
     687**93882.201 ms**
     688
     689{{{
     690Gather  (cost=230200.46..235882.48 rows=2211 width=121) (actual time=3427.813..93875.377 rows=1683 loops=1)
     691  Workers Planned: 3
     692  Workers Launched: 3
     693  ->  Nested Loop Left Join  (cost=229200.46..234661.38 rows=713 width=121) (actual time=3393.680..41801.988 rows=421 loops=4)
     694        ->  Merge Left Join  (cost=229200.03..229252.13 rows=713 width=85) (actual time=3393.619..3396.837 rows=421 loops=4)
     695              Merge Cond: (s.id = pc.song_id)
     696              ->  Sort  (cost=225567.13..225568.91 rows=713 width=77) (actual time=3342.494..3342.739 rows=421 loops=4)
     697                    Sort Key: s.id
     698                    Sort Method: quicksort  Memory: 48kB
     699                    Worker 0:  Sort Method: quicksort  Memory: 44kB
     700                    Worker 1:  Sort Method: quicksort  Memory: 44kB
     701                    Worker 2:  Sort Method: quicksort  Memory: 72kB
     702                    ->  Nested Loop Left Join  (cost=209283.95..225533.34 rows=713 width=77) (actual time=3254.123..3342.167 rows=421 loops=4)
     703                          ->  Parallel Hash Right Join  (cost=209283.53..225211.18 rows=713 width=72) (actual time=3254.061..3337.679 rows=421 loops=4)
     704                                Hash Cond: (at.song_id = s.id)
     705                                ->  Parallel Seq Scan on album_tracks at  (cost=0.00..14292.12 rows=435812 width=16) (actual time=0.016..39.432 rows=337754 loops=4)
     706                                ->  Parallel Hash  (cost=209276.62..209276.62 rows=553 width=64) (actual time=3253.381..3253.392 rows=421 loops=4)
     707                                      Buckets: 4096  Batches: 1  Memory Usage: 192kB
     708                                      ->  Hash Left Join  (cost=164727.43..209276.62 rows=553 width=64) (actual time=3174.557..3252.826 rows=421 loops=4)
     709                                            Hash Cond: (s.id = sc.song_id)
     710                                            ->  Hash Left Join  (cost=909.90..45457.64 rows=553 width=56) (actual time=52.511..130.411 rows=421 loops=4)
     711                                                  Hash Cond: (al.label_id = l.id)
     712                                                  ->  Hash Left Join  (cost=896.46..45442.74 rows=553 width=41) (actual time=52.297..129.994 rows=421 loops=4)
     713                                                        Hash Cond: (a.id = al.artist_id)
     714                                                        ->  Nested Loop Left Join  (cost=0.42..44542.96 rows=553 width=41) (actual time=41.010..118.277 rows=421 loops=4)
     715                                                              ->  Parallel Seq Scan on songs s  (cost=0.00..42527.60 rows=553 width=29) (actual time=40.894..112.485 rows=421 loops=4)
     716                                                                    Filter: ((title)::text = 'Harmony'::text)
     717                                                                    Rows Removed by Filter: 487388
     718                                                              ->  Index Scan using artists_pkey on artists a  (cost=0.42..3.64 rows=1 width=20) (actual time=0.012..0.012 rows=1 loops=1683)
     719                                                                    Index Cond: (id = s.owner_artist_id)
     720                                                        ->  Hash  (cost=521.02..521.02 rows=30002 width=16) (actual time=11.075..11.076 rows=30003 loops=4)
     721                                                              Buckets: 32768  Batches: 1  Memory Usage: 1663kB
     722                                                              ->  Seq Scan on artist_labels al  (cost=0.00..521.02 rows=30002 width=16) (actual time=0.053..4.694 rows=30003 loops=4)
     723                                                  ->  Hash  (cost=8.75..8.75 rows=375 width=31) (actual time=0.190..0.191 rows=375 loops=4)
     724                                                        Buckets: 1024  Batches: 1  Memory Usage: 33kB
     725                                                        ->  Seq Scan on labels l  (cost=0.00..8.75 rows=375 width=31) (actual time=0.030..0.089 rows=375 loops=4)
     726                                            ->  Hash  (cost=161618.58..161618.58 rows=175916 width=16) (actual time=3120.501..3120.503 rows=635893 loops=4)
     727                                                  Buckets: 1048576 (originally 262144)  Batches: 1 (originally 1)  Memory Usage: 38000kB
     728                                                  ->  Subquery Scan on sc  (cost=158100.26..161618.58 rows=175916 width=16) (actual time=2662.167..2922.708 rows=635893 loops=4)
     729                                                        ->  HashAggregate  (cost=158100.26..159859.42 rows=175916 width=16) (actual time=2662.160..2862.916 rows=635893 loops=4)
     730                                                              Group Key: song_streams.song_id
     731                                                              Batches: 1  Memory Usage: 65553kB
     732                                                              Worker 0:  Batches: 1  Memory Usage: 65553kB
     733                                                              Worker 1:  Batches: 1  Memory Usage: 65553kB
     734                                                              Worker 2:  Batches: 1  Memory Usage: 65553kB
     735                                                              ->  Seq Scan on song_streams  (cost=0.00..124221.84 rows=6775684 width=8) (actual time=0.040..834.432 rows=6775685 loops=4)
     736                          ->  Index Scan using albums_pkey on albums alb  (cost=0.42..0.45 rows=1 width=21) (actual time=0.010..0.010 rows=1 loops=1683)
     737                                Index Cond: (id = at.album_id)
     738              ->  Sort  (cost=3632.91..3657.15 rows=9698 width=16) (actual time=51.065..52.559 rows=10235 loops=4)
     739                    Sort Key: pc.song_id
     740                    Sort Method: quicksort  Memory: 706kB
     741                    Worker 0:  Sort Method: quicksort  Memory: 706kB
     742                    Worker 1:  Sort Method: quicksort  Memory: 706kB
     743                    Worker 2:  Sort Method: quicksort  Memory: 706kB
     744                    ->  Subquery Scan on pc  (cost=2796.77..2990.73 rows=9698 width=16) (actual time=45.054..47.748 rows=10288 loops=4)
     745                          ->  HashAggregate  (cost=2796.77..2893.75 rows=9698 width=16) (actual time=45.048..46.739 rows=10288 loops=4)
     746                                Group Key: playlist_tracks.song_id
     747                                Batches: 1  Memory Usage: 1425kB
     748                                Worker 0:  Batches: 1  Memory Usage: 1425kB
     749                                Worker 1:  Batches: 1  Memory Usage: 1425kB
     750                                Worker 2:  Batches: 1  Memory Usage: 1425kB
     751                                ->  Seq Scan on playlist_tracks  (cost=0.00..2171.18 rows=125118 width=8) (actual time=0.038..14.065 rows=125118 loops=4)
     752        ->  Index Scan using idx_sag_mv_song_id on song_average_grade_mv sag  (cost=0.43..7.58 rows=1 width=24) (actual time=91.275..91.276 rows=1 loops=1683)
     753              Index Cond: (song_id = s.id)
     754Planning Time: 2.976 ms
     755JIT:
     756  Functions: 272
     757"  Options: Inlining false, Optimization false, Expressions true, Deforming true"
     758"  Timing: Generation 16.724 ms (Deform 7.604 ms), Inlining 0.000 ms, Optimization 6.390 ms, Emission 157.809 ms, Total 180.923 ms"
     759Execution Time: 93882.201 ms
     760}}}
     761
     762За оптимизирање на секвенцијалните скенирање на табелите {{{artist_labels}}}, {{{album_tracks}}} и {{{songs}}} ги креираме индексите:
     763
     764{{{
     765CREATE INDEX idx_songs_title
     766ON songs(title);
     767
     768CREATE INDEX idx_album_tracks_song_id
     769ON album_tracks(song_id);
     770
     771CREATE INDEX idx_artist_labels_artist_id
     772ON artist_labels(artist_id);
     773}}}
     774
     775==== Време за извршување со индекси
     776
     777**3599.404 ms**
     778
     779{{{
     780Gather  (cost=188600.68..198746.59 rows=2211 width=121) (actual time=3136.649..3592.763 rows=1683 loops=1)
     781  Workers Planned: 1
     782  Workers Launched: 1
     783  ->  Nested Loop Left Join  (cost=187600.68..197525.49 rows=1301 width=121) (actual time=3114.199..3121.952 rows=842 loops=2)
     784        ->  Merge Left Join  (cost=187600.25..187655.31 rows=1301 width=85) (actual time=3114.146..3116.186 rows=842 loops=2)
     785              Merge Cond: (s.id = pc.song_id)
     786              ->  Sort  (cost=183967.34..183970.60 rows=1301 width=77) (actual time=3064.947..3065.100 rows=842 loops=2)
     787                    Sort Key: s.id
     788                    Sort Method: quicksort  Memory: 143kB
     789                    Worker 0:  Sort Method: quicksort  Memory: 40kB
     790                    ->  Hash Left Join  (cost=166553.22..183900.05 rows=1301 width=77) (actual time=3047.496..3064.384 rows=842 loops=2)
     791                          Hash Cond: (s.id = sc.song_id)
     792                          ->  Nested Loop Left Join  (cost=2735.67..20079.09 rows=1301 width=69) (actual time=64.333..80.679 rows=842 loops=2)
     793                                ->  Nested Loop Left Join  (cost=2735.25..19491.26 rows=1301 width=64) (actual time=64.294..76.539 rows=842 loops=2)
     794                                      ->  Hash Left Join  (cost=2734.82..10204.79 rows=1301 width=56) (actual time=64.235..70.862 rows=842 loops=2)
     795                                            Hash Cond: (al.label_id = l.id)
     796                                            ->  Nested Loop Left Join  (cost=2721.39..10187.90 rows=1301 width=41) (actual time=64.055..70.410 rows=842 loops=2)
     797                                                  ->  Parallel Hash Left Join  (cost=2721.10..9762.21 rows=1301 width=41) (actual time=64.004..67.464 rows=842 loops=2)
     798                                                        Hash Cond: (s.owner_artist_id = a.id)
     799                                                        ->  Parallel Bitmap Heap Scan on songs s  (cost=29.56..7067.26 rows=1301 width=29) (actual time=0.629..2.990 rows=842 loops=2)
     800                                                              Recheck Cond: ((title)::text = 'Harmony'::text)
     801                                                              Heap Blocks: exact=1395
     802                                                              ->  Bitmap Index Scan on idx_songs_title  (cost=0.00..29.01 rows=2211 width=0) (actual time=0.323..0.324 rows=1683 loops=1)
     803                                                                    Index Cond: ((title)::text = 'Harmony'::text)
     804                                                        ->  Parallel Hash  (cost=1956.24..1956.24 rows=58824 width=20) (actual time=62.392..62.393 rows=50000 loops=2)
     805                                                              Buckets: 131072  Batches: 1  Memory Usage: 6496kB
     806                                                              ->  Parallel Seq Scan on artists a  (cost=0.00..1956.24 rows=58824 width=20) (actual time=38.029..44.369 rows=50000 loops=2)
     807                                                  ->  Index Scan using idx_artist_labels_artist_id on artist_labels al  (cost=0.29..0.32 rows=1 width=16) (actual time=0.003..0.003 rows=0 loops=1683)
     808                                                        Index Cond: (artist_id = a.id)
     809                                            ->  Hash  (cost=8.75..8.75 rows=375 width=31) (actual time=0.155..0.155 rows=375 loops=2)
     810                                                  Buckets: 1024  Batches: 1  Memory Usage: 33kB
     811                                                  ->  Seq Scan on labels l  (cost=0.00..8.75 rows=375 width=31) (actual time=0.031..0.079 rows=375 loops=2)
     812                                      ->  Index Scan using idx_album_tracks_song_id on album_tracks at  (cost=0.43..7.13 rows=1 width=16) (actual time=0.006..0.006 rows=1 loops=1683)
     813                                            Index Cond: (song_id = s.id)
     814                                ->  Index Scan using albums_pkey on albums alb  (cost=0.42..0.45 rows=1 width=21) (actual time=0.004..0.004 rows=1 loops=1683)
     815                                      Index Cond: (id = at.album_id)
     816                          ->  Hash  (cost=161618.60..161618.60 rows=175916 width=16) (actual time=2982.071..2982.073 rows=635893 loops=2)
     817                                Buckets: 1048576 (originally 262144)  Batches: 1 (originally 1)  Memory Usage: 38000kB
     818                                ->  Subquery Scan on sc  (cost=158100.27..161618.60 rows=175916 width=16) (actual time=2526.994..2790.788 rows=635893 loops=2)
     819                                      ->  HashAggregate  (cost=158100.27..159859.43 rows=175916 width=16) (actual time=2526.987..2726.430 rows=635893 loops=2)
     820                                            Group Key: song_streams.song_id
     821                                            Batches: 1  Memory Usage: 65553kB
     822                                            Worker 0:  Batches: 1  Memory Usage: 65553kB
     823                                            ->  Seq Scan on song_streams  (cost=0.00..124221.85 rows=6775685 width=8) (actual time=0.049..708.679 rows=6775685 loops=2)
     824              ->  Sort  (cost=3632.91..3657.15 rows=9698 width=16) (actual time=49.155..49.933 rows=10235 loops=2)
     825                    Sort Key: pc.song_id
     826                    Sort Method: quicksort  Memory: 706kB
     827                    Worker 0:  Sort Method: quicksort  Memory: 706kB
     828                    ->  Subquery Scan on pc  (cost=2796.77..2990.73 rows=9698 width=16) (actual time=43.313..46.006 rows=10288 loops=2)
     829                          ->  HashAggregate  (cost=2796.77..2893.75 rows=9698 width=16) (actual time=43.307..44.952 rows=10288 loops=2)
     830                                Group Key: playlist_tracks.song_id
     831                                Batches: 1  Memory Usage: 1425kB
     832                                Worker 0:  Batches: 1  Memory Usage: 1425kB
     833                                ->  Seq Scan on playlist_tracks  (cost=0.00..2171.18 rows=125118 width=8) (actual time=0.039..13.544 rows=125118 loops=2)
     834        ->  Index Scan using idx_sag_mv_song_id on song_average_grade_mv sag  (cost=0.43..7.58 rows=1 width=24) (actual time=0.006..0.006 rows=1 loops=1683)
     835              Index Cond: (song_id = s.id)
     836Planning Time: 3.163 ms
     837JIT:
     838  Functions: 132
     839"  Options: Inlining false, Optimization false, Expressions true, Deforming true"
     840"  Timing: Generation 7.561 ms (Deform 3.504 ms), Inlining 0.000 ms, Optimization 2.789 ms, Emission 73.213 ms, Total 83.563 ms"
     841Execution Time: 3599.404 ms
     842}}}
     843
     844Бидејќи сепак имаме секвенцијално скенирање на табелата {{{song_streams}}} поради групирањето на слушања по песна, дополнително оптимизираме со материјализиран погледи:
     845
     846{{{
     847create materialized view song_stream_counts_mv as
     848select
     849    song_id,
     850    count(*) as streams
     851from song_streams
     852group by song_id;
     853
     854
     855create materialized view song_playlist_counts_mv as
     856select
     857    song_id,
     858    count(*) as saved_in_playlists
     859from playlist_tracks
     860group by song_id;
     861
     862
     863create or replace view song_detailed_info_view_mvs as
     864select
     865    s.title as title,
     866    a.display_name as artist_name,
     867    coalesce(l.name, 'SOLO') as label_name,
     868    coalesce(sc.streams, 0) as streams,
     869    coalesce(alb.title, 'SINGLE') as album_title,
     870    coalesce(pc.saved_in_playlists, 0) as saved_in_playlists,
     871    sag.num_reviews,
     872    ROUND(sag.avg_grade, 2) AS avg_grade
     873from songs s
     874left join artists a on a.id = s.owner_artist_id
     875left join artist_labels al on al.artist_id = a.id
     876left join labels l on l.id = al.label_id
     877left join album_tracks at on at.song_id = s.id
     878left join albums alb on alb.id = at.album_id
     879left join song_stream_counts_mv sc on sc.song_id = s.id
     880left join song_playlist_counts_mv pc on pc.song_id = s.id
     881left join song_average_grade_mv sag on sag.song_id = s.id;
     882}}}
     883
     884
     885==== Време за извршување на прашалникот по додавање на материјализирани погледи
     886
     887**333.811 ms**
     888
     889{{{
     890Gather  (cost=25188.45..57377.30 rows=2211 width=145) (actual time=113.872..333.525 rows=1683 loops=1)
     891  Workers Planned: 3
     892  Workers Launched: 3
     893  ->  Parallel Hash Right Join  (cost=24188.45..56156.20 rows=713 width=145) (actual time=84.308..207.282 rows=421 loops=4)
     894        Hash Cond: (sag.song_id = s.id)
     895        ->  Parallel Seq Scan on song_average_grade_mv sag  (cost=0.00..29616.74 rows=625674 width=24) (actual time=0.016..50.181 rows=484897 loops=4)
     896        ->  Parallel Hash  (cost=24176.94..24176.94 rows=921 width=85) (actual time=83.322..83.338 rows=421 loops=4)
     897              Buckets: 4096  Batches: 1  Memory Usage: 256kB
     898              ->  Hash Left Join  (cost=10077.11..24176.94 rows=921 width=85) (actual time=20.990..64.447 rows=421 loops=4)
     899                    Hash Cond: (s.id = pc.song_id)
     900                    ->  Nested Loop Left Join  (cost=9789.63..23885.95 rows=921 width=77) (actual time=17.300..60.507 rows=421 loops=4)
     901                          ->  Nested Loop Left Join  (cost=9789.21..23469.82 rows=921 width=72) (actual time=17.283..57.817 rows=421 loops=4)
     902                                ->  Hash Left Join  (cost=9788.78..16895.77 rows=921 width=64) (actual time=17.245..53.588 rows=421 loops=4)
     903                                      Hash Cond: (al.label_id = l.id)
     904                                      ->  Nested Loop Left Join  (cost=9775.35..16879.89 rows=921 width=49) (actual time=17.040..53.223 rows=421 loops=4)
     905                                            ->  Parallel Hash Left Join  (cost=9775.06..16578.54 rows=921 width=49) (actual time=16.984..51.378 rows=421 loops=4)
     906                                                  Hash Cond: (s.owner_artist_id = a.id)
     907                                                  ->  Parallel Hash Right Join  (cost=7083.52..13884.59 rows=921 width=37) (actual time=4.483..38.155 rows=421 loops=4)
     908                                                        Hash Cond: (sc.song_id = s.id)
     909                                                        ->  Parallel Seq Scan on song_stream_counts_mv sc  (cost=0.00..6105.55 rows=264955 width=16) (actual time=0.013..14.911 rows=158973 loops=4)
     910                                                        ->  Parallel Hash  (cost=7067.26..7067.26 rows=1301 width=29) (actual time=4.275..4.276 rows=421 loops=4)
     911                                                              Buckets: 4096  Batches: 1  Memory Usage: 160kB
     912                                                              ->  Parallel Bitmap Heap Scan on songs s  (cost=29.56..7067.26 rows=1301 width=29) (actual time=0.718..3.921 rows=421 loops=4)
     913                                                                    Recheck Cond: ((title)::text = 'Harmony'::text)
     914                                                                    Heap Blocks: exact=455
     915                                                                    ->  Bitmap Index Scan on idx_songs_title  (cost=0.00..29.01 rows=2211 width=0) (actual time=0.386..0.386 rows=1683 loops=1)
     916                                                                          Index Cond: ((title)::text = 'Harmony'::text)
     917                                                  ->  Parallel Hash  (cost=1956.24..1956.24 rows=58824 width=20) (actual time=12.017..12.018 rows=25000 loops=4)
     918                                                        Buckets: 131072  Batches: 1  Memory Usage: 6528kB
     919                                                        ->  Parallel Seq Scan on artists a  (cost=0.00..1956.24 rows=58824 width=20) (actual time=0.166..3.968 rows=25000 loops=4)
     920                                            ->  Index Scan using idx_artist_labels_artist_id on artist_labels al  (cost=0.29..0.32 rows=1 width=16) (actual time=0.004..0.004 rows=0 loops=1683)
     921                                                  Index Cond: (artist_id = a.id)
     922                                      ->  Hash  (cost=8.75..8.75 rows=375 width=31) (actual time=0.179..0.180 rows=375 loops=4)
     923                                            Buckets: 1024  Batches: 1  Memory Usage: 33kB
     924                                            ->  Seq Scan on labels l  (cost=0.00..8.75 rows=375 width=31) (actual time=0.030..0.078 rows=375 loops=4)
     925                                ->  Index Scan using idx_album_tracks_song_id on album_tracks at  (cost=0.43..7.13 rows=1 width=16) (actual time=0.009..0.009 rows=1 loops=1683)
     926                                      Index Cond: (song_id = s.id)
     927                          ->  Index Scan using albums_pkey on albums alb  (cost=0.42..0.45 rows=1 width=21) (actual time=0.006..0.006 rows=1 loops=1683)
     928                                Index Cond: (id = at.album_id)
     929                    ->  Hash  (cost=158.88..158.88 rows=10288 width=16) (actual time=3.568..3.568 rows=10288 loops=4)
     930                          Buckets: 16384  Batches: 1  Memory Usage: 611kB
     931                          ->  Seq Scan on song_playlist_counts_mv pc  (cost=0.00..158.88 rows=10288 width=16) (actual time=0.022..1.349 rows=10288 loops=4)
     932Planning Time: 135.345 ms
     933Execution Time: 333.811 ms
     934}}}
     935
     936
     937=== 8. Анализа на поглед 8, историја на слушање песни од корисниците
     938
     939Прашалник кој го тестираме:
     940
     941{{{
     942SELECT *
     943FROM streams_history
     944WHERE username='adriana_klein_511'
     945ORDER BY streamed_at DESC;
     946}}}
     947
     948==== Време за извршување без дополнителни индекси
     949
     950**0.404 ms**
     951
     952{{{
     953Sort  (cost=52.13..52.15 rows=7 width=58) (actual time=0.333..0.335 rows=15 loops=1)
     954  Sort Key: ss.streamed_at DESC
     955  Sort Method: quicksort  Memory: 26kB
     956  ->  Nested Loop  (cost=1.72..52.03 rows=7 width=58) (actual time=0.072..0.316 rows=15 loops=1)
     957        ->  Nested Loop  (cost=1.28..48.40 rows=7 width=62) (actual time=0.061..0.195 rows=15 loops=1)
     958              ->  Nested Loop  (cost=0.86..45.09 rows=7 width=49) (actual time=0.049..0.094 rows=15 loops=1)
     959                    ->  Index Scan using users_username_key on users u  (cost=0.42..8.44 rows=1 width=25) (actual time=0.029..0.030 rows=1 loops=1)
     960                          Index Cond: ((username)::text = 'adriana_klein_511'::text)
     961                    ->  Index Scan using idx_song_streams_user_id on song_streams ss  (cost=0.43..36.57 rows=8 width=32) (actual time=0.014..0.056 rows=15 loops=1)
     962                          Index Cond: (user_id = u.id)
     963              ->  Index Scan using songs_pkey on songs s  (cost=0.43..0.47 rows=1 width=21) (actual time=0.006..0.006 rows=1 loops=15)
     964                    Index Cond: (id = ss.song_id)
     965        ->  Index Scan using playback_sessions_pkey on playback_sessions ps  (cost=0.43..0.52 rows=1 width=12) (actual time=0.007..0.007 rows=1 loops=15)
     966              Index Cond: (id = ss.playback_session_id)
     967Planning Time: 91.388 ms
     968Execution Time: 0.404 ms
     969}}}
     970
     971Бидејќи се корситат индексите креирани за примарните клучеви, како и индексот {{{ idx_song_streams_user_id }}}, нема потреба за дополнителна оптимизација на прашалникот