Changes between Version 4 and Version 5 of Indexes


Ignore:
Timestamp:
02/06/26 15:22:03 (2 days ago)
Author:
233194
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Indexes

    v4 v5  
    195195
    196196Without indexes: \\
    197 Buffers: shared hit=7684 \\
    198 Planning Time: 0.021 ms \\
    199 Execution Time: 506.953 ms \\
     197{{{
     198"Limit  (cost=24715.33..24715.37 rows=15 width=76) (actual time=514.170..521.754 rows=0.00 loops=1)"
     199"  Output: c.type, c.brand, c.name, (count(bc.component_id)), (avg(rb.value))"
     200"  Buffers: shared hit=7621"
     201"  ->  Sort  (cost=24715.33..24724.79 rows=3783 width=76) (actual time=514.169..521.752 rows=0.00 loops=1)"
     202"        Output: c.type, c.brand, c.name, (count(bc.component_id)), (avg(rb.value))"
     203"        Sort Key: (count(bc.component_id)) DESC, (avg(rb.value)) DESC"
     204"        Sort Method: quicksort  Memory: 25kB"
     205"        Buffers: shared hit=7621"
     206"        ->  Finalize HashAggregate  (cost=24452.26..24622.51 rows=3783 width=76) (actual time=514.159..521.743 rows=0.00 loops=1)"
     207"              Output: c.type, c.brand, c.name, count(bc.component_id), avg(rb.value)"
     208"              Group Key: c.type, c.brand, c.name"
     209"              Filter: (avg(rb.value) >= 4.5)"
     210"              Batches: 1  Memory Usage: 289kB"
     211"              Rows Removed by Filter: 8"
     212"              Buffers: shared hit=7621"
     213"              ->  Gather  (cost=21177.79..24043.66 rows=27240 width=76) (actual time=512.069..521.649 rows=24.00 loops=1)"
     214"                    Output: c.type, c.brand, c.name, (PARTIAL count(bc.component_id)), (PARTIAL avg(rb.value))"
     215"                    Workers Planned: 2"
     216"                    Workers Launched: 2"
     217"                    Buffers: shared hit=7621"
     218"                    ->  Partial HashAggregate  (cost=20177.79..20319.66 rows=11350 width=76) (actual time=477.550..477.607 rows=8.00 loops=3)"
     219"                          Output: c.type, c.brand, c.name, PARTIAL count(bc.component_id), PARTIAL avg(rb.value)"
     220"                          Group Key: c.type, c.brand, c.name"
     221"                          Batches: 1  Memory Usage: 289kB"
     222"                          Buffers: shared hit=7621"
     223"                          Worker 0:  actual time=465.044..465.084 rows=8.00 loops=1"
     224"                            Batches: 1  Memory Usage: 289kB"
     225"                            Buffers: shared hit=2485"
     226"                          Worker 1:  actual time=456.082..456.143 rows=8.00 loops=1"
     227"                            Batches: 1  Memory Usage: 289kB"
     228"                            Buffers: shared hit=2404"
     229"                          ->  Hash Join  (cost=6196.24..16477.60 rows=296015 width=45) (actual time=143.788..343.710 rows=236717.33 loops=3)"
     230"                                Output: c.type, c.brand, c.name, bc.component_id, rb.value"
     231"                                Hash Cond: (bc.build_id = b.id)"
     232"                                Buffers: shared hit=7621"
     233"                                Worker 0:  actual time=158.769..344.695 rows=224941.00 loops=1"
     234"                                  Buffers: shared hit=2485"
     235"                                Worker 1:  actual time=153.000..337.176 rows=207233.00 loops=1"
     236"                                  Buffers: shared hit=2404"
     237"                                ->  Hash Join  (cost=368.38..6768.87 rows=250000 width=44) (actual time=6.150..89.973 rows=200000.00 loops=3)"
     238"                                      Output: c.type, c.brand, c.name, bc.component_id, bc.build_id"
     239"                                      Inner Unique: true"
     240"                                      Hash Cond: (bc.component_id = c.id)"
     241"                                      Buffers: shared hit=3583"
     242"                                      Worker 0:  actual time=7.786..86.909 rows=189810.00 loops=1"
     243"                                        Buffers: shared hit=1139"
     244"                                      Worker 1:  actual time=7.464..86.431 rows=174825.00 loops=1"
     245"                                        Buffers: shared hit=1058"
     246"                                      ->  Parallel Seq Scan on public.build_component bc  (cost=0.00..5744.00 rows=250000 width=8) (actual time=0.013..16.572 rows=200000.00 loops=3)"
     247"                                            Output: bc.build_id, bc.component_id, bc.num_components"
     248"                                            Buffers: shared hit=3244"
     249"                                            Worker 0:  actual time=0.018..16.106 rows=189810.00 loops=1"
     250"                                              Buffers: shared hit=1026"
     251"                                            Worker 1:  actual time=0.017..15.861 rows=174825.00 loops=1"
     252"                                              Buffers: shared hit=945"
     253"                                      ->  Hash  (cost=226.50..226.50 rows=11350 width=40) (actual time=6.054..6.055 rows=11350.00 loops=3)"
     254"                                            Output: c.type, c.brand, c.name, c.id"
     255"                                            Buckets: 16384  Batches: 1  Memory Usage: 962kB"
     256"                                            Buffers: shared hit=339"
     257"                                            Worker 0:  actual time=7.679..7.679 rows=11350.00 loops=1"
     258"                                              Buffers: shared hit=113"
     259"                                            Worker 1:  actual time=7.350..7.350 rows=11350.00 loops=1"
     260"                                              Buffers: shared hit=113"
     261"                                            ->  Seq Scan on public.components c  (cost=0.00..226.50 rows=11350 width=40) (actual time=0.344..2.832 rows=11350.00 loops=3)"
     262"                                                  Output: c.type, c.brand, c.name, c.id"
     263"                                                  Buffers: shared hit=339"
     264"                                                  Worker 0:  actual time=0.450..3.615 rows=11350.00 loops=1"
     265"                                                    Buffers: shared hit=113"
     266"                                                  Worker 1:  actual time=0.571..3.620 rows=11350.00 loops=1"
     267"                                                    Buffers: shared hit=113"
     268"                                ->  Hash  (cost=4717.80..4717.80 rows=88805 width=13) (actual time=137.365..137.366 rows=88769.00 loops=3)"
     269"                                      Output: b.id, rb.value, rb.build_id"
     270"                                      Buckets: 131072  Batches: 1  Memory Usage: 5186kB"
     271"                                      Buffers: shared hit=4038"
     272"                                      Worker 0:  actual time=150.702..150.703 rows=88769.00 loops=1"
     273"                                        Buffers: shared hit=1346"
     274"                                      Worker 1:  actual time=145.234..145.235 rows=88769.00 loops=1"
     275"                                        Buffers: shared hit=1346"
     276"                                      ->  Hash Join  (cost=3110.85..4717.80 rows=88805 width=13) (actual time=45.967..109.261 rows=88769.00 loops=3)"
     277"                                            Output: b.id, rb.value, rb.build_id"
     278"                                            Inner Unique: true"
     279"                                            Hash Cond: (rb.build_id = b.id)"
     280"                                            Buffers: shared hit=4038"
     281"                                            Worker 0:  actual time=51.541..120.247 rows=88769.00 loops=1"
     282"                                              Buffers: shared hit=1346"
     283"                                            Worker 1:  actual time=46.388..115.886 rows=88769.00 loops=1"
     284"                                              Buffers: shared hit=1346"
     285"                                            ->  Seq Scan on public.rating_build rb  (cost=0.00..1373.04 rows=89104 width=9) (actual time=0.407..8.817 rows=89104.00 loops=3)"
     286"                                                  Output: rb.build_id, rb.user_id, rb.value"
     287"                                                  Buffers: shared hit=1446"
     288"                                                  Worker 0:  actual time=0.566..8.558 rows=89104.00 loops=1"
     289"                                                    Buffers: shared hit=482"
     290"                                                  Worker 1:  actual time=0.638..11.340 rows=89104.00 loops=1"
     291"                                                    Buffers: shared hit=482"
     292"                                            ->  Hash  (cost=2176.50..2176.50 rows=74748 width=4) (actual time=45.199..45.200 rows=74720.00 loops=3)"
     293"                                                  Output: b.id"
     294"                                                  Buckets: 131072  Batches: 1  Memory Usage: 3651kB"
     295"                                                  Buffers: shared hit=2592"
     296"                                                  Worker 0:  actual time=50.414..50.414 rows=74720.00 loops=1"
     297"                                                    Buffers: shared hit=864"
     298"                                                  Worker 1:  actual time=45.487..45.487 rows=74720.00 loops=1"
     299"                                                    Buffers: shared hit=864"
     300"                                                  ->  Seq Scan on public.build b  (cost=0.00..2176.50 rows=74748 width=4) (actual time=0.354..27.279 rows=74720.00 loops=3)"
     301"                                                        Output: b.id"
     302"                                                        Filter: (b.created_at >= (CURRENT_DATE - '1 year'::interval))"
     303"                                                        Rows Removed by Filter: 280"
     304"                                                        Buffers: shared hit=2592"
     305"                                                        Worker 0:  actual time=0.594..30.487 rows=74720.00 loops=1"
     306"                                                          Buffers: shared hit=864"
     307"                                                        Worker 1:  actual time=0.450..28.109 rows=74720.00 loops=1"
     308"                                                          Buffers: shared hit=864"
     309"Planning:"
     310"  Buffers: shared hit=61 dirtied=1"
     311"Planning Time: 2.660 ms"
     312"Execution Time: 523.396 ms"
     313}}}
    200314
    201315With indexes: \\
    202 Buffers: shared hit=6379 read=351 \\
    203 Planning Time: 0.022 ms \\
    204 Execution Time: 468.190 ms \\
    205 
    206 Result: The date index improved query performance, while not much, still a modest improvement reducing it from 506.953ms to 468.190ms. \\
     316{{{
     317"Limit  (cost=23597.58..23597.61 rows=15 width=76) (actual time=450.819..457.739 rows=0.00 loops=1)"
     318"  Output: c.type, c.brand, c.name, (count(bc.component_id)), (avg(rb.value))"
     319"  Buffers: shared hit=6180 read=340"
     320"  ->  Sort  (cost=23597.58..23607.03 rows=3783 width=76) (actual time=450.818..457.738 rows=0.00 loops=1)"
     321"        Output: c.type, c.brand, c.name, (count(bc.component_id)), (avg(rb.value))"
     322"        Sort Key: (count(bc.component_id)) DESC, (avg(rb.value)) DESC"
     323"        Sort Method: quicksort  Memory: 25kB"
     324"        Buffers: shared hit=6180 read=340"
     325"        ->  Finalize HashAggregate  (cost=23334.51..23504.76 rows=3783 width=76) (actual time=450.813..457.732 rows=0.00 loops=1)"
     326"              Output: c.type, c.brand, c.name, count(bc.component_id), avg(rb.value)"
     327"              Group Key: c.type, c.brand, c.name"
     328"              Filter: (avg(rb.value) >= 4.5)"
     329"              Batches: 1  Memory Usage: 289kB"
     330"              Rows Removed by Filter: 8"
     331"              Buffers: shared hit=6180 read=340"
     332"              ->  Gather  (cost=20060.04..22925.91 rows=27240 width=76) (actual time=449.068..457.644 rows=24.00 loops=1)"
     333"                    Output: c.type, c.brand, c.name, (PARTIAL count(bc.component_id)), (PARTIAL avg(rb.value))"
     334"                    Workers Planned: 2"
     335"                    Workers Launched: 2"
     336"                    Buffers: shared hit=6180 read=340"
     337"                    ->  Partial HashAggregate  (cost=19060.04..19201.91 rows=11350 width=76) (actual time=419.604..419.656 rows=8.00 loops=3)"
     338"                          Output: c.type, c.brand, c.name, PARTIAL count(bc.component_id), PARTIAL avg(rb.value)"
     339"                          Group Key: c.type, c.brand, c.name"
     340"                          Batches: 1  Memory Usage: 289kB"
     341"                          Buffers: shared hit=6180 read=340"
     342"                          Worker 0:  actual time=406.116..406.170 rows=8.00 loops=1"
     343"                            Batches: 1  Memory Usage: 289kB"
     344"                            Buffers: shared hit=2093"
     345"                          Worker 1:  actual time=404.070..404.112 rows=8.00 loops=1"
     346"                            Batches: 1  Memory Usage: 289kB"
     347"                            Buffers: shared hit=1996"
     348"                          ->  Parallel Hash Join  (cost=6144.52..15359.85 rows=296015 width=45) (actual time=75.562..301.742 rows=236717.33 loops=3)"
     349"                                Output: c.type, c.brand, c.name, bc.component_id, rb.value"
     350"                                Hash Cond: (bc.build_id = rb.build_id)"
     351"                                Buffers: shared hit=6180 read=340"
     352"                                Worker 0:  actual time=69.636..294.647 rows=244174.00 loops=1"
     353"                                  Buffers: shared hit=2093"
     354"                                Worker 1:  actual time=65.038..288.820 rows=222711.00 loops=1"
     355"                                  Buffers: shared hit=1996"
     356"                                ->  Hash Join  (cost=3479.22..10533.80 rows=249160 width=48) (actual time=64.759..205.120 rows=199253.33 loops=3)"
     357"                                      Output: c.type, c.brand, c.name, bc.component_id, bc.build_id, b.id"
     358"                                      Inner Unique: true"
     359"                                      Hash Cond: (bc.component_id = c.id)"
     360"                                      Buffers: shared hit=6175"
     361"                                      Worker 0:  actual time=69.584..208.007 rows=205692.00 loops=1"
     362"                                        Buffers: shared hit=2093"
     363"                                      Worker 1:  actual time=64.969..204.957 rows=187846.00 loops=1"
     364"                                        Buffers: shared hit=1996"
     365"                                      ->  Hash Join  (cost=3110.85..9511.13 rows=249160 width=12) (actual time=59.879..150.606 rows=199253.33 loops=3)"
     366"                                            Output: bc.component_id, bc.build_id, b.id"
     367"                                            Inner Unique: true"
     368"                                            Hash Cond: (bc.build_id = b.id)"
     369"                                            Buffers: shared hit=5836"
     370"                                            Worker 0:  actual time=63.648..155.149 rows=205692.00 loops=1"
     371"                                              Buffers: shared hit=1980"
     372"                                            Worker 1:  actual time=61.520..151.281 rows=187846.00 loops=1"
     373"                                              Buffers: shared hit=1883"
     374"                                            ->  Parallel Seq Scan on public.build_component bc  (cost=0.00..5744.00 rows=250000 width=8) (actual time=0.007..14.818 rows=200000.00 loops=3)"
     375"                                                  Output: bc.build_id, bc.component_id, bc.num_components"
     376"                                                  Buffers: shared hit=3244"
     377"                                                  Worker 0:  actual time=0.010..15.585 rows=206460.00 loops=1"
     378"                                                    Buffers: shared hit=1116"
     379"                                                  Worker 1:  actual time=0.008..15.532 rows=188515.00 loops=1"
     380"                                                    Buffers: shared hit=1019"
     381"                                            ->  Hash  (cost=2176.50..2176.50 rows=74748 width=4) (actual time=59.628..59.628 rows=74720.00 loops=3)"
     382"                                                  Output: b.id"
     383"                                                  Buckets: 131072  Batches: 1  Memory Usage: 3651kB"
     384"                                                  Buffers: shared hit=2592"
     385"                                                  Worker 0:  actual time=63.410..63.410 rows=74720.00 loops=1"
     386"                                                    Buffers: shared hit=864"
     387"                                                  Worker 1:  actual time=61.314..61.314 rows=74720.00 loops=1"
     388"                                                    Buffers: shared hit=864"
     389"                                                  ->  Seq Scan on public.build b  (cost=0.00..2176.50 rows=74748 width=4) (actual time=0.289..34.946 rows=74720.00 loops=3)"
     390"                                                        Output: b.id"
     391"                                                        Filter: (b.created_at >= (CURRENT_DATE - '1 year'::interval))"
     392"                                                        Rows Removed by Filter: 280"
     393"                                                        Buffers: shared hit=2592"
     394"                                                        Worker 0:  actual time=0.417..34.850 rows=74720.00 loops=1"
     395"                                                          Buffers: shared hit=864"
     396"                                                        Worker 1:  actual time=0.422..41.270 rows=74720.00 loops=1"
     397"                                                          Buffers: shared hit=864"
     398"                                      ->  Hash  (cost=226.50..226.50 rows=11350 width=40) (actual time=4.786..4.788 rows=11350.00 loops=3)"
     399"                                            Output: c.type, c.brand, c.name, c.id"
     400"                                            Buckets: 16384  Batches: 1  Memory Usage: 962kB"
     401"                                            Buffers: shared hit=339"
     402"                                            Worker 0:  actual time=5.790..5.790 rows=11350.00 loops=1"
     403"                                              Buffers: shared hit=113"
     404"                                            Worker 1:  actual time=3.373..3.374 rows=11350.00 loops=1"
     405"                                              Buffers: shared hit=113"
     406"                                            ->  Seq Scan on public.components c  (cost=0.00..226.50 rows=11350 width=40) (actual time=0.191..2.117 rows=11350.00 loops=3)"
     407"                                                  Output: c.type, c.brand, c.name, c.id"
     408"                                                  Buffers: shared hit=339"
     409"                                                  Worker 0:  actual time=0.264..2.779 rows=11350.00 loops=1"
     410"                                                    Buffers: shared hit=113"
     411"                                                  Worker 1:  actual time=0.290..1.620 rows=11350.00 loops=1"
     412"                                                    Buffers: shared hit=113"
     413"                                ->  Parallel Hash  (cost=2201.20..2201.20 rows=37127 width=9) (actual time=10.621..10.622 rows=29701.33 loops=3)"
     414"                                      Output: rb.value, rb.build_id"
     415"                                      Buckets: 131072  Batches: 1  Memory Usage: 5216kB"
     416"                                      Buffers: shared hit=5 read=340"
     417"                                      Worker 0:  actual time=0.024..0.024 rows=0.00 loops=1"
     418"                                      Worker 1:  actual time=0.017..0.017 rows=0.00 loops=1"
     419"                                      ->  Parallel Index Only Scan using idx_rating_build_build_value on public.rating_build rb  (cost=0.42..2201.20 rows=37127 width=9) (actual time=0.015..14.847 rows=89104.00 loops=1)"
     420"                                            Output: rb.value, rb.build_id"
     421"                                            Heap Fetches: 0"
     422"                                            Index Searches: 1"
     423"                                            Buffers: shared hit=5 read=340"
     424"Planning:"
     425"  Buffers: shared hit=84 read=9"
     426"Planning Time: 3.357 ms"
     427"Execution Time: 458.529 ms"
     428}}}
     429
     430Result: The date index improved query performance, while not much, still a modest improvement reducing it from 523.396ms to 458.529ms. \\
    207431
    208432=== Scenario 8: User Reputation Leaderboard Report ===
    209433
    210434Without indexes: \\
    211 Buffers: shared hit=142884 dirtied=1, temp read=495 written=849 \\
    212 Planning Time: 0.029 ms \\
    213 Execution Time: 553.368 ms \\
     435{{{
     436"Limit  (cost=13848.06..13848.08 rows=10 width=135) (actual time=338.505..338.510 rows=10.00 loops=1)"
     437"  Output: u.username, u.email, (count(b.id)), (COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)), (round(COALESCE((avg((avg(rb.value)))), '0'::numeric), 2)), ((((((count(b.id)) * 10))::numeric + ((COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)) * '5'::numeric)) + (COALESCE((avg((avg(rb.value)))), '0'::numeric) * '20'::numeric)))"
     438"  Buffers: shared hit=142841, temp read=231 written=584"
     439"  ->  Sort  (cost=13848.06..13848.56 rows=200 width=135) (actual time=338.504..338.508 rows=10.00 loops=1)"
     440"        Output: u.username, u.email, (count(b.id)), (COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)), (round(COALESCE((avg((avg(rb.value)))), '0'::numeric), 2)), ((((((count(b.id)) * 10))::numeric + ((COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)) * '5'::numeric)) + (COALESCE((avg((avg(rb.value)))), '0'::numeric) * '20'::numeric)))"
     441"        Sort Key: ((((((count(b.id)) * 10))::numeric + ((COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)) * '5'::numeric)) + (COALESCE((avg((avg(rb.value)))), '0'::numeric) * '20'::numeric))) DESC"
     442"        Sort Method: top-N heapsort  Memory: 26kB"
     443"        Buffers: shared hit=142841, temp read=231 written=584"
     444"        ->  Nested Loop  (cost=12461.53..13843.74 rows=200 width=135) (actual time=142.982..324.335 rows=47142.00 loops=1)"
     445"              Output: u.username, u.email, (count(b.id)), (COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)), round(COALESCE((avg((avg(rb.value)))), '0'::numeric), 2), (((((count(b.id)) * 10))::numeric + ((COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)) * '5'::numeric)) + (COALESCE((avg((avg(rb.value)))), '0'::numeric) * '20'::numeric))"
     446"              Inner Unique: true"
     447"              Buffers: shared hit=142841, temp read=231 written=584"
     448"              ->  HashAggregate  (cost=12461.24..12464.24 rows=200 width=76) (actual time=142.958..207.997 rows=47142.00 loops=1)"
     449"                    Output: b.user_id, count(b.id), COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric), avg((avg(rb.value)))"
     450"                    Group Key: b.user_id"
     451"                    Batches: 5  Memory Usage: 8257kB  Disk Usage: 3344kB"
     452"                    Buffers: shared hit=1415, temp read=231 written=584"
     453"                    ->  GroupAggregate  (cost=0.84..11187.64 rows=63680 width=48) (actual time=0.061..113.081 rows=63679.00 loops=1)"
     454"                          Output: b.id, b.user_id, count(DISTINCT fb.user_id), avg(rb.value)"
     455"                          Group Key: b.id"
     456"                          Buffers: shared hit=1415"
     457"                          ->  Incremental Sort  (cost=0.84..9824.23 rows=75655 width=17) (actual time=0.055..65.316 rows=94843.00 loops=1)"
     458"                                Output: b.id, b.user_id, fb.user_id, rb.value"
     459"                                Sort Key: b.id, fb.user_id"
     460"                                Presorted Key: b.id"
     461"                                Full-sort Groups: 2934  Sort Method: quicksort  Average Memory: 25kB  Peak Memory: 25kB"
     462"                                Buffers: shared hit=1415"
     463"                                ->  Merge Left Join  (cost=0.72..6838.88 rows=75655 width=17) (actual time=0.036..48.651 rows=94843.00 loops=1)"
     464"                                      Output: b.id, b.user_id, fb.user_id, rb.value"
     465"                                      Merge Cond: (b.id = rb.build_id)"
     466"                                      Buffers: shared hit=1415"
     467"                                      ->  Merge Left Join  (cost=0.30..2979.52 rows=63680 width=12) (actual time=0.023..21.860 rows=63679.00 loops=1)"
     468"                                            Output: b.id, b.user_id, fb.user_id"
     469"                                            Merge Cond: (b.id = fb.build_id)"
     470"                                            Buffers: shared hit=1070"
     471"                                            ->  Index Scan using build_pkey on public.build b  (cost=0.29..2820.29 rows=63680 width=8) (actual time=0.009..16.139 rows=63679.00 loops=1)"
     472"                                                  Output: b.id, b.user_id, b.name, b.created_at, b.description, b.total_price, b.is_approved"
     473"                                                  Filter: b.is_approved"
     474"                                                  Rows Removed by Filter: 11321"
     475"                                                  Index Searches: 1"
     476"                                                  Buffers: shared hit=1070"
     477"                                            ->  Sort  (cost=0.01..0.02 rows=1 width=8) (actual time=0.012..0.013 rows=0.00 loops=1)"
     478"                                                  Output: fb.user_id, fb.build_id"
     479"                                                  Sort Key: fb.build_id"
     480"                                                  Sort Method: quicksort  Memory: 25kB"
     481"                                                  ->  Seq Scan on public.favorite_build fb  (cost=0.00..0.00 rows=1 width=8) (actual time=0.008..0.009 rows=0.00 loops=1)"
     482"                                                        Output: fb.user_id, fb.build_id"
     483"                                      ->  Index Only Scan using idx_rating_build_build_value on public.rating_build rb  (cost=0.42..2720.98 rows=89104 width=9) (actual time=0.012..8.719 rows=89104.00 loops=1)"
     484"                                            Output: rb.build_id, rb.value"
     485"                                            Heap Fetches: 0"
     486"                                            Index Searches: 1"
     487"                                            Buffers: shared hit=345"
     488"              ->  Index Scan using users_pkey on public.users u  (cost=0.29..6.87 rows=1 width=35) (actual time=0.002..0.002 rows=1.00 loops=47142)"
     489"                    Output: u.id, u.username, u.password, u.email"
     490"                    Index Cond: (u.id = b.user_id)"
     491"                    Index Searches: 47142"
     492"                    Buffers: shared hit=141426"
     493"Planning:"
     494"  Buffers: shared hit=53 read=3 dirtied=3"
     495"Planning Time: 1.559 ms"
     496"Execution Time: 350.055 ms"
     497}}}
    214498
    215499With indexes: \\
    216 Buffers: shared hit=142892 read=1, temp read=231 written=584 \\
    217 Planning Time: 0.022 ms \\
    218 Execution Time: 345.192 ms \\
    219 
    220 Result: Here the improvement is much more noticeable than on Scenario 7, reducing the time from 553.368ms to 345.192ms. \\
     500{{{
     501"Limit  (cost=13848.06..13848.08 rows=10 width=135) (actual time=310.840..310.844 rows=10.00 loops=1)"
     502"  Output: u.username, u.email, (count(b.id)), (COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)), (round(COALESCE((avg((avg(rb.value)))), '0'::numeric), 2)), ((((((count(b.id)) * 10))::numeric + ((COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)) * '5'::numeric)) + (COALESCE((avg((avg(rb.value)))), '0'::numeric) * '20'::numeric)))"
     503"  Buffers: shared hit=142841, temp read=231 written=584"
     504"  ->  Sort  (cost=13848.06..13848.56 rows=200 width=135) (actual time=310.839..310.842 rows=10.00 loops=1)"
     505"        Output: u.username, u.email, (count(b.id)), (COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)), (round(COALESCE((avg((avg(rb.value)))), '0'::numeric), 2)), ((((((count(b.id)) * 10))::numeric + ((COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)) * '5'::numeric)) + (COALESCE((avg((avg(rb.value)))), '0'::numeric) * '20'::numeric)))"
     506"        Sort Key: ((((((count(b.id)) * 10))::numeric + ((COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)) * '5'::numeric)) + (COALESCE((avg((avg(rb.value)))), '0'::numeric) * '20'::numeric))) DESC"
     507"        Sort Method: top-N heapsort  Memory: 26kB"
     508"        Buffers: shared hit=142841, temp read=231 written=584"
     509"        ->  Nested Loop  (cost=12461.53..13843.74 rows=200 width=135) (actual time=127.073..297.426 rows=47142.00 loops=1)"
     510"              Output: u.username, u.email, (count(b.id)), (COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)), round(COALESCE((avg((avg(rb.value)))), '0'::numeric), 2), (((((count(b.id)) * 10))::numeric + ((COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric)) * '5'::numeric)) + (COALESCE((avg((avg(rb.value)))), '0'::numeric) * '20'::numeric))"
     511"              Inner Unique: true"
     512"              Buffers: shared hit=142841, temp read=231 written=584"
     513"              ->  HashAggregate  (cost=12461.24..12464.24 rows=200 width=76) (actual time=127.053..185.307 rows=47142.00 loops=1)"
     514"                    Output: b.user_id, count(b.id), COALESCE(sum((count(DISTINCT fb.user_id))), '0'::numeric), avg((avg(rb.value)))"
     515"                    Group Key: b.user_id"
     516"                    Batches: 5  Memory Usage: 8257kB  Disk Usage: 3344kB"
     517"                    Buffers: shared hit=1415, temp read=231 written=584"
     518"                    ->  GroupAggregate  (cost=0.84..11187.64 rows=63680 width=48) (actual time=0.083..99.800 rows=63679.00 loops=1)"
     519"                          Output: b.id, b.user_id, count(DISTINCT fb.user_id), avg(rb.value)"
     520"                          Group Key: b.id"
     521"                          Buffers: shared hit=1415"
     522"                          ->  Incremental Sort  (cost=0.84..9824.23 rows=75655 width=17) (actual time=0.078..55.977 rows=94843.00 loops=1)"
     523"                                Output: b.id, b.user_id, fb.user_id, rb.value"
     524"                                Sort Key: b.id, fb.user_id"
     525"                                Presorted Key: b.id"
     526"                                Full-sort Groups: 2934  Sort Method: quicksort  Average Memory: 25kB  Peak Memory: 25kB"
     527"                                Buffers: shared hit=1415"
     528"                                ->  Merge Left Join  (cost=0.72..6838.88 rows=75655 width=17) (actual time=0.035..41.138 rows=94843.00 loops=1)"
     529"                                      Output: b.id, b.user_id, fb.user_id, rb.value"
     530"                                      Merge Cond: (b.id = rb.build_id)"
     531"                                      Buffers: shared hit=1415"
     532"                                      ->  Merge Left Join  (cost=0.30..2979.52 rows=63680 width=12) (actual time=0.023..18.353 rows=63679.00 loops=1)"
     533"                                            Output: b.id, b.user_id, fb.user_id"
     534"                                            Merge Cond: (b.id = fb.build_id)"
     535"                                            Buffers: shared hit=1070"
     536"                                            ->  Index Scan using build_pkey on public.build b  (cost=0.29..2820.29 rows=63680 width=8) (actual time=0.010..13.634 rows=63679.00 loops=1)"
     537"                                                  Output: b.id, b.user_id, b.name, b.created_at, b.description, b.total_price, b.is_approved"
     538"                                                  Filter: b.is_approved"
     539"                                                  Rows Removed by Filter: 11321"
     540"                                                  Index Searches: 1"
     541"                                                  Buffers: shared hit=1070"
     542"                                            ->  Sort  (cost=0.01..0.02 rows=1 width=8) (actual time=0.012..0.012 rows=0.00 loops=1)"
     543"                                                  Output: fb.user_id, fb.build_id"
     544"                                                  Sort Key: fb.build_id"
     545"                                                  Sort Method: quicksort  Memory: 25kB"
     546"                                                  ->  Seq Scan on public.favorite_build fb  (cost=0.00..0.00 rows=1 width=8) (actual time=0.008..0.008 rows=0.00 loops=1)"
     547"                                                        Output: fb.user_id, fb.build_id"
     548"                                      ->  Index Only Scan using idx_rating_build_build_value on public.rating_build rb  (cost=0.42..2720.98 rows=89104 width=9) (actual time=0.010..7.703 rows=89104.00 loops=1)"
     549"                                            Output: rb.build_id, rb.value"
     550"                                            Heap Fetches: 0"
     551"                                            Index Searches: 1"
     552"                                            Buffers: shared hit=345"
     553"              ->  Index Scan using users_pkey on public.users u  (cost=0.29..6.87 rows=1 width=35) (actual time=0.002..0.002 rows=1.00 loops=47142)"
     554"                    Output: u.id, u.username, u.password, u.email"
     555"                    Index Cond: (u.id = b.user_id)"
     556"                    Index Searches: 47142"
     557"                    Buffers: shared hit=141426"
     558"Planning:"
     559"  Buffers: shared hit=20"
     560"Planning Time: 0.552 ms"
     561"Execution Time: 321.427 ms"
     562}}}
     563
     564Result: Here the improvement is modest but still, the time is reduced from 350.055ms to 321.427ms. \\
    221565
    222566=== Scenario 9: Budget Tier Popularity Report ===
    223567
    224568Without indexes: \\
    225 Buffers: shared hit=1366 read=30 \\
    226 Planning Time: 0.020 ms \\
    227 Execution Time: 131.234 ms \\
     569{{{
     570"Limit  (cost=10028.88..10028.91 rows=15 width=144) (actual time=129.793..129.800 rows=3.00 loops=1)"
     571"  Output: engagement_stats.price_tier, engagement_stats.builds_count, (round(engagement_stats.avg_favorites, 1)), (round(COALESCE(engagement_stats.avg_rating, '0'::numeric), 2)), engagement_stats.unique_builders, (round((((((engagement_stats.builds_count * 2))::numeric + (engagement_stats.avg_favorites * '3'::numeric)) + (COALESCE(engagement_stats.avg_rating, '0'::numeric) * '10'::numeric)) + ((engagement_stats.unique_builders)::numeric * 1.5)), 2))"
     572"  Buffers: shared hit=1346 read=28"
     573"  ->  Sort  (cost=10028.88..10105.53 rows=30660 width=144) (actual time=129.790..129.795 rows=3.00 loops=1)"
     574"        Output: engagement_stats.price_tier, engagement_stats.builds_count, (round(engagement_stats.avg_favorites, 1)), (round(COALESCE(engagement_stats.avg_rating, '0'::numeric), 2)), engagement_stats.unique_builders, (round((((((engagement_stats.builds_count * 2))::numeric + (engagement_stats.avg_favorites * '3'::numeric)) + (COALESCE(engagement_stats.avg_rating, '0'::numeric) * '10'::numeric)) + ((engagement_stats.unique_builders)::numeric * 1.5)), 2))"
     575"        Sort Key: (round((((((engagement_stats.builds_count * 2))::numeric + (engagement_stats.avg_favorites * '3'::numeric)) + (COALESCE(engagement_stats.avg_rating, '0'::numeric) * '10'::numeric)) + ((engagement_stats.unique_builders)::numeric * 1.5)), 2)) DESC"
     576"        Sort Method: quicksort  Memory: 25kB"
     577"        Buffers: shared hit=1346 read=28"
     578"        ->  Subquery Scan on engagement_stats  (cost=7102.18..9276.65 rows=30660 width=144) (actual time=122.973..129.780 rows=3.00 loops=1)"
     579"              Output: engagement_stats.price_tier, engagement_stats.builds_count, round(engagement_stats.avg_favorites, 1), round(COALESCE(engagement_stats.avg_rating, '0'::numeric), 2), engagement_stats.unique_builders, round((((((engagement_stats.builds_count * 2))::numeric + (engagement_stats.avg_favorites * '3'::numeric)) + (COALESCE(engagement_stats.avg_rating, '0'::numeric) * '10'::numeric)) + ((engagement_stats.unique_builders)::numeric * 1.5)), 2)"
     580"              Buffers: shared hit=1346 read=28"
     581"              ->  GroupAggregate  (cost=7102.18..8356.85 rows=30660 width=112) (actual time=122.969..129.762 rows=3.00 loops=1)"
     582"                    Output: (CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END), count(DISTINCT b.id), avg(COALESCE(f.favorites_count, '0'::bigint)), avg(rb.value), count(DISTINCT b.user_id)"
     583"                    Group Key: (CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END)"
     584"                    Buffers: shared hit=1346 read=28"
     585"                    ->  Sort  (cost=7102.18..7196.31 rows=37655 width=53) (actual time=108.154..112.232 rows=47343.00 loops=1)"
     586"                          Output: (CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END), b.id, f.favorites_count, rb.value, b.user_id"
     587"                          Sort Key: (CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END), b.id"
     588"                          Sort Method: quicksort  Memory: 3562kB"
     589"                          Buffers: shared hit=1346 read=28"
     590"                          ->  Hash Left Join  (cost=2252.07..4240.29 rows=37655 width=53) (actual time=9.040..47.523 rows=47343.00 loops=1)"
     591"                                Output: CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END, b.id, f.favorites_count, rb.value, b.user_id"
     592"                                Inner Unique: true"
     593"                                Hash Cond: (b.id = f.build_id)"
     594"                                Buffers: shared hit=1346 read=28"
     595"                                ->  Hash Right Join  (cost=2252.02..3858.97 rows=37655 width=19) (actual time=9.018..36.039 rows=47343.00 loops=1)"
     596"                                      Output: b.total_price, b.id, b.user_id, rb.value"
     597"                                      Inner Unique: true"
     598"                                      Hash Cond: (rb.build_id = b.id)"
     599"                                      Buffers: shared hit=1346 read=28"
     600"                                      ->  Seq Scan on public.rating_build rb  (cost=0.00..1373.04 rows=89104 width=9) (actual time=0.018..4.017 rows=89104.00 loops=1)"
     601"                                            Output: rb.build_id, rb.user_id, rb.value"
     602"                                            Buffers: shared hit=482"
     603"                                      ->  Hash  (cost=1855.83..1855.83 rows=31695 width=14) (actual time=8.927..8.928 rows=31774.00 loops=1)"
     604"                                            Output: b.total_price, b.id, b.user_id"
     605"                                            Buckets: 32768  Batches: 1  Memory Usage: 1746kB"
     606"                                            Buffers: shared hit=864 read=28"
     607"                                            ->  Bitmap Heap Scan on public.build b  (cost=437.17..1855.83 rows=31695 width=14) (actual time=1.272..5.897 rows=31774.00 loops=1)"
     608"                                                  Output: b.total_price, b.id, b.user_id"
     609"                                                  Recheck Cond: (b.is_approved AND (b.created_at >= (CURRENT_DATE - '6 mons'::interval)))"
     610"                                                  Heap Blocks: exact=864"
     611"                                                  Buffers: shared hit=864 read=28"
     612"                                                  ->  Bitmap Index Scan on idx_build_approved_date  (cost=0.00..429.25 rows=31695 width=0) (actual time=1.198..1.198 rows=31774.00 loops=1)"
     613"                                                        Index Cond: ((b.is_approved = true) AND (b.created_at >= (CURRENT_DATE - '6 mons'::interval)))"
     614"                                                        Index Searches: 1"
     615"                                                        Buffers: shared read=28"
     616"                                ->  Hash  (cost=0.04..0.04 rows=1 width=12) (actual time=0.015..0.017 rows=0.00 loops=1)"
     617"                                      Output: f.favorites_count, f.build_id"
     618"                                      Buckets: 1024  Batches: 1  Memory Usage: 8kB"
     619"                                      ->  Subquery Scan on f  (cost=0.01..0.04 rows=1 width=12) (actual time=0.015..0.015 rows=0.00 loops=1)"
     620"                                            Output: f.favorites_count, f.build_id"
     621"                                            ->  GroupAggregate  (cost=0.01..0.03 rows=1 width=12) (actual time=0.014..0.015 rows=0.00 loops=1)"
     622"                                                  Output: favorite_build.build_id, count(DISTINCT favorite_build.user_id)"
     623"                                                  Group Key: favorite_build.build_id"
     624"                                                  ->  Sort  (cost=0.01..0.02 rows=1 width=8) (actual time=0.014..0.014 rows=0.00 loops=1)"
     625"                                                        Output: favorite_build.build_id, favorite_build.user_id"
     626"                                                        Sort Key: favorite_build.build_id, favorite_build.user_id"
     627"                                                        Sort Method: quicksort  Memory: 25kB"
     628"                                                        ->  Seq Scan on public.favorite_build  (cost=0.00..0.00 rows=1 width=8) (actual time=0.008..0.008 rows=0.00 loops=1)"
     629"                                                              Output: favorite_build.build_id, favorite_build.user_id"
     630"Planning:"
     631"  Buffers: shared hit=29 dirtied=1"
     632"Planning Time: 1.567 ms"
     633"Execution Time: 130.489 ms"
     634}}}
    228635
    229636With indexes: \\
    230 Buffers: shared hit=1396 \\
    231 Planning Time: 0.029 ms \\
    232 Execution Time: 125.615 ms \\
    233 
    234 Result: Modest improvement, but the index still helped out with unnecessary reads, reducing time from 131.234ms to 125.615ms. \\
    235 
    236 
    237 
    238 
     637{{{
     638"Limit  (cost=10028.88..10028.91 rows=15 width=144) (actual time=117.098..117.102 rows=3.00 loops=1)"
     639"  Output: engagement_stats.price_tier, engagement_stats.builds_count, (round(engagement_stats.avg_favorites, 1)), (round(COALESCE(engagement_stats.avg_rating, '0'::numeric), 2)), engagement_stats.unique_builders, (round((((((engagement_stats.builds_count * 2))::numeric + (engagement_stats.avg_favorites * '3'::numeric)) + (COALESCE(engagement_stats.avg_rating, '0'::numeric) * '10'::numeric)) + ((engagement_stats.unique_builders)::numeric * 1.5)), 2))"
     640"  Buffers: shared hit=1374"
     641"  ->  Sort  (cost=10028.88..10105.53 rows=30660 width=144) (actual time=117.097..117.101 rows=3.00 loops=1)"
     642"        Output: engagement_stats.price_tier, engagement_stats.builds_count, (round(engagement_stats.avg_favorites, 1)), (round(COALESCE(engagement_stats.avg_rating, '0'::numeric), 2)), engagement_stats.unique_builders, (round((((((engagement_stats.builds_count * 2))::numeric + (engagement_stats.avg_favorites * '3'::numeric)) + (COALESCE(engagement_stats.avg_rating, '0'::numeric) * '10'::numeric)) + ((engagement_stats.unique_builders)::numeric * 1.5)), 2))"
     643"        Sort Key: (round((((((engagement_stats.builds_count * 2))::numeric + (engagement_stats.avg_favorites * '3'::numeric)) + (COALESCE(engagement_stats.avg_rating, '0'::numeric) * '10'::numeric)) + ((engagement_stats.unique_builders)::numeric * 1.5)), 2)) DESC"
     644"        Sort Method: quicksort  Memory: 25kB"
     645"        Buffers: shared hit=1374"
     646"        ->  Subquery Scan on engagement_stats  (cost=7102.18..9276.65 rows=30660 width=144) (actual time=110.076..117.088 rows=3.00 loops=1)"
     647"              Output: engagement_stats.price_tier, engagement_stats.builds_count, round(engagement_stats.avg_favorites, 1), round(COALESCE(engagement_stats.avg_rating, '0'::numeric), 2), engagement_stats.unique_builders, round((((((engagement_stats.builds_count * 2))::numeric + (engagement_stats.avg_favorites * '3'::numeric)) + (COALESCE(engagement_stats.avg_rating, '0'::numeric) * '10'::numeric)) + ((engagement_stats.unique_builders)::numeric * 1.5)), 2)"
     648"              Buffers: shared hit=1374"
     649"              ->  GroupAggregate  (cost=7102.18..8356.85 rows=30660 width=112) (actual time=110.071..117.076 rows=3.00 loops=1)"
     650"                    Output: (CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END), count(DISTINCT b.id), avg(COALESCE(f.favorites_count, '0'::bigint)), avg(rb.value), count(DISTINCT b.user_id)"
     651"                    Group Key: (CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END)"
     652"                    Buffers: shared hit=1374"
     653"                    ->  Sort  (cost=7102.18..7196.31 rows=37655 width=53) (actual time=95.917..99.817 rows=47343.00 loops=1)"
     654"                          Output: (CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END), b.id, f.favorites_count, rb.value, b.user_id"
     655"                          Sort Key: (CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END), b.id"
     656"                          Sort Method: quicksort  Memory: 3562kB"
     657"                          Buffers: shared hit=1374"
     658"                          ->  Hash Left Join  (cost=2252.07..4240.29 rows=37655 width=53) (actual time=9.370..39.857 rows=47343.00 loops=1)"
     659"                                Output: CASE WHEN (b.total_price < '500'::numeric) THEN 'Budget'::text WHEN (b.total_price < '1000'::numeric) THEN 'Mid-Range'::text WHEN (b.total_price < '2000'::numeric) THEN 'High-End'::text ELSE 'Enthusiast'::text END, b.id, f.favorites_count, rb.value, b.user_id"
     660"                                Inner Unique: true"
     661"                                Hash Cond: (b.id = f.build_id)"
     662"                                Buffers: shared hit=1374"
     663"                                ->  Hash Right Join  (cost=2252.02..3858.97 rows=37655 width=19) (actual time=9.347..30.148 rows=47343.00 loops=1)"
     664"                                      Output: b.total_price, b.id, b.user_id, rb.value"
     665"                                      Inner Unique: true"
     666"                                      Hash Cond: (rb.build_id = b.id)"
     667"                                      Buffers: shared hit=1374"
     668"                                      ->  Seq Scan on public.rating_build rb  (cost=0.00..1373.04 rows=89104 width=9) (actual time=0.019..3.375 rows=89104.00 loops=1)"
     669"                                            Output: rb.build_id, rb.user_id, rb.value"
     670"                                            Buffers: shared hit=482"
     671"                                      ->  Hash  (cost=1855.83..1855.83 rows=31695 width=14) (actual time=9.250..9.250 rows=31774.00 loops=1)"
     672"                                            Output: b.total_price, b.id, b.user_id"
     673"                                            Buckets: 32768  Batches: 1  Memory Usage: 1746kB"
     674"                                            Buffers: shared hit=892"
     675"                                            ->  Bitmap Heap Scan on public.build b  (cost=437.17..1855.83 rows=31695 width=14) (actual time=1.482..6.062 rows=31774.00 loops=1)"
     676"                                                  Output: b.total_price, b.id, b.user_id"
     677"                                                  Recheck Cond: (b.is_approved AND (b.created_at >= (CURRENT_DATE - '6 mons'::interval)))"
     678"                                                  Heap Blocks: exact=864"
     679"                                                  Buffers: shared hit=892"
     680"                                                  ->  Bitmap Index Scan on idx_build_approved_date  (cost=0.00..429.25 rows=31695 width=0) (actual time=1.387..1.388 rows=31774.00 loops=1)"
     681"                                                        Index Cond: ((b.is_approved = true) AND (b.created_at >= (CURRENT_DATE - '6 mons'::interval)))"
     682"                                                        Index Searches: 1"
     683"                                                        Buffers: shared hit=28"
     684"                                ->  Hash  (cost=0.04..0.04 rows=1 width=12) (actual time=0.015..0.017 rows=0.00 loops=1)"
     685"                                      Output: f.favorites_count, f.build_id"
     686"                                      Buckets: 1024  Batches: 1  Memory Usage: 8kB"
     687"                                      ->  Subquery Scan on f  (cost=0.01..0.04 rows=1 width=12) (actual time=0.015..0.016 rows=0.00 loops=1)"
     688"                                            Output: f.favorites_count, f.build_id"
     689"                                            ->  GroupAggregate  (cost=0.01..0.03 rows=1 width=12) (actual time=0.014..0.015 rows=0.00 loops=1)"
     690"                                                  Output: favorite_build.build_id, count(DISTINCT favorite_build.user_id)"
     691"                                                  Group Key: favorite_build.build_id"
     692"                                                  ->  Sort  (cost=0.01..0.02 rows=1 width=8) (actual time=0.014..0.014 rows=0.00 loops=1)"
     693"                                                        Output: favorite_build.build_id, favorite_build.user_id"
     694"                                                        Sort Key: favorite_build.build_id, favorite_build.user_id"
     695"                                                        Sort Method: quicksort  Memory: 25kB"
     696"                                                        ->  Seq Scan on public.favorite_build  (cost=0.00..0.00 rows=1 width=8) (actual time=0.007..0.008 rows=0.00 loops=1)"
     697"                                                              Output: favorite_build.build_id, favorite_build.user_id"
     698"Planning:"
     699"  Buffers: shared hit=17"
     700"Planning Time: 0.718 ms"
     701"Execution Time: 117.824 ms"
     702}}}
     703
     704Result: Modest improvement, but the index still helped out with unnecessary reads, reducing time from 130.489ms to 117.824ms. \\
     705
     706
     707
     708