如何提高PostgreSQL查询的执行时间?

时间:2020-03-02 00:09:49

标签: postgresql performance filtering execution-time

因此,我想缩短查询执行时间,大约需要90毫秒,最坏的情况是大约150毫秒。基本上,我需要获取每个NBA球队的当前(本赛季)统计数据。类似于-> https://stats.nba.com/teams/traditional/?sort=W_PCT&dir=-1,除了(MIN,BLKA,PFD)。

player_stats表中的列:id,game_id,team_id,opponent_team_id,player_id,分钟,fg,fga,fgp,fg3,fg3a,fg3p,ft,fta,ftp,orb,drb,trb,ast,stl,blk, tov,pf,pts,plus_minus,赛季,季后赛。

“团队”表中的列:ID,团队名称,简称,其他名称,链接,会议。

游戏表中的列:id,home_team_id,home_team_score,away_team_id,away_team_score,日期,季后赛,赛季。

我有索引,据我所知它们可以正常工作。很抱歉,这是初学者的问题,但是我不擅长编写数据库查询。

SELECT 
    t.name AS team_name,
    CONCAT('/teams/', t.short_name) AS team_url,
    hg.hg + ag.ag AS tot_games,
    hg.home_game_wons + ag.away_game_wons AS games_won,
    hg.home_game_losses + ag.away_game_losses AS games_loss,
    ROUND(((hg.home_game_wons + ag.away_game_wons) / ROUND(hg.hg + ag.ag)) * 100, 2) AS w_l_p,
    ROUND(SUM(ps.fg) / ROUND(hg.hg + ag.ag), 1) AS fg,
    ROUND(SUM(ps.fga) / ROUND(hg.hg + ag.ag), 1) AS fga, 
    ROUND(avg(ps.fgp)::decimal * 100, 1) AS fgp, 
    ROUND(SUM(ps.fg3) / ROUND(hg.hg + ag.ag), 1) AS fg3, 
    ROUND(SUM(ps.fg3a) / ROUND(hg.hg + ag.ag), 1) AS fg3a, 
    ROUND(avg(ps.fg3p)::decimal *100,1) AS fg3p, 
    ROUND(SUM(ps.ft) / ROUND(hg.hg + ag.ag), 1) AS ft, 
    ROUND(SUM(ps.fta) / ROUND(hg.hg + ag.ag), 1) AS fta, 
    ROUND(avg(ps.ftp)::decimal * 100,1) AS ftp, 
    ROUND(SUM(ps.orb) / ROUND(hg.hg + ag.ag), 1) AS orb, 
    ROUND(SUM(ps.drb) / ROUND(hg.hg + ag.ag), 1) AS drb, 
    ROUND(SUM(ps.trb) / ROUND(hg.hg + ag.ag), 1) AS trb, 
    ROUND(SUM(ps.ast) / ROUND(hg.hg + ag.ag), 1) AS ast, 
    ROUND(SUM(ps.stl) / ROUND(hg.hg + ag.ag), 1) AS stl, 
    ROUND(SUM(ps.blk) / ROUND(hg.hg + ag.ag), 1) AS blk, 
    ROUND(SUM(ps.tov) / ROUND(hg.hg + ag.ag), 1) AS tov, 
    ROUND(SUM(ps.pf) / ROUND(hg.hg + ag.ag), 1) AS pf, 
    ROUND(SUM(ps.pts) / ROUND(hg.hg + ag.ag), 1) AS pts,
    ROUND((hg.home_opponent_scored + ag.away_opponent_scored) / ROUND(hg.hg + ag.ag), 1) AS opponent_pts
FROM public.player_stats AS ps
LEFT JOIN public.teams AS t
    ON ps.team_id = t.id
LEFT JOIN (
    SELECT `enter code here`
    home_team_id,
    COUNT(
        CASE 
           WHEN home_team_score > away_team_score THEN 1
        END
    ) AS home_game_wons,
    COUNT(
        CASE 
           WHEN home_team_score < away_team_score THEN 1
        END
    ) AS home_game_losses,
    SUM(away_team_score) AS home_opponent_scored,
    COUNT(home_team_id)::decimal AS hg
    FROM public.games
    WHERE season = '2019-20' AND playoff = false 
    GROUP BY home_team_id
) AS hg
    ON ps.team_id = hg.home_team_id
LEFT JOIN (
    SELECT 
    away_team_id,
    COUNT(
        CASE 
           WHEN home_team_score < away_team_score THEN 1
        END
    ) AS away_game_wons,
    COUNT(
        CASE 
           WHEN home_team_score > away_team_score THEN 1
        END
    ) AS away_game_losses,
    SUM(home_team_score) AS away_opponent_scored,
    COUNT(away_team_id)::int AS ag
    FROM public.games
    WHERE season = '2019-20' AND playoff = false
    GROUP BY away_team_id
) as ag
    ON ps.team_id = ag.away_team_id
WHERE ps.season = '2019-20' AND ps.playoff = false
GROUP BY 
    t.name, 
    t.short_name, 
    hg.home_game_wons, 
    hg.home_game_losses,
    hg.home_opponent_scored,
    ag.away_game_wons, 
    ag.away_game_losses,
    ag.away_opponent_scored,
    hg.hg,
    ag.ag
ORDER BY games_won DESC, games_loss ASC;

说明|

first 29 rows

next 28 rows

enter image description here

Sort  (cost=45826.48..45873.10 rows=18648 width=852) (actual time=51.570..51.575 rows=30 loops=1)
  Sort Key: ((hg.home_game_wons + ag.away_game_wons)) DESC, ((hg.home_game_losses + ag.away_game_losses))
  Sort Method: quicksort  Memory: 40kB
  Buffers: shared hit=1031 read=247
  ->  Finalize GroupAggregate  (cost=28708.80..37489.71 rows=18648 width=852) (actual time=39.190..51.507 rows=30 loops=1)
        Group Key: t.name, t.short_name, hg.home_game_wons, hg.home_game_losses, hg.home_opponent_scored, ag.away_game_wons, ag.away_game_losses, ag.away_opponent_scored, hg.hg, ag.ag
        Buffers: shared hit=1031 read=247
        ->  Gather Merge  (cost=28708.80..30847.76 rows=10969 width=348) (actual time=38.346..50.761 rows=57 loops=1)
              Workers Planned: 1
              Workers Launched: 1
              Buffers: shared hit=2014 read=342
              ->  Partial GroupAggregate  (cost=27708.79..28613.74 rows=10969 width=348) (actual time=33.335..44.570 rows=28 loops=2)
                    Group Key: t.name, t.short_name, hg.home_game_wons, hg.home_game_losses, hg.home_opponent_scored, ag.away_game_wons, ag.away_game_losses, ag.away_opponent_scored, hg.hg, ag.ag
                    Buffers: shared hit=2014 read=342
                    ->  Sort  (cost=27708.79..27736.22 rows=10969 width=216) (actual time=32.724..33.952 rows=10609 loops=2)
                          Sort Key: t.name, t.short_name, hg.home_game_wons, hg.home_game_losses, hg.home_opponent_scored, ag.away_game_wons, ag.away_game_losses, ag.away_opponent_scored, hg.hg, ag.ag
                          Sort Method: quicksort  Memory: 3275kB
                          Worker 0:  Sort Method: quicksort  Memory: 2665kB
                          Buffers: shared hit=2014 read=342
                          ->  Hash Left Join  (cost=2077.34..26972.71 rows=10969 width=216) (actual time=0.986..15.344 rows=10609 loops=2)
                                Hash Cond: (ps.team_id = t.id)
                                Buffers: shared hit=1988 read=342
                                ->  Merge Left Join  (cost=2060.14..26926.34 rows=10969 width=172) (actual time=0.926..12.449 rows=10609 loops=2)
                                      Merge Cond: (ps.team_id = ag.away_team_id)
                                      Buffers: shared hit=1981 read=342
                                      ->  Merge Left Join  (cost=1030.29..25759.18 rows=10969 width=144) (actual time=0.554..9.803 rows=10609 loops=2)
                                            Merge Cond: (ps.team_id = hg.home_team_id)
                                            Buffers: shared hit=1941 read=342
                                            ->  Parallel Index Scan using IDX__PLAYER_STATS_1 on player_stats ps  (cost=0.43..24592.03 rows=10969 width=88) (actual time=0.066..5.746 rows=10609 loops=2)
                                                  Index Cond: (((season)::text = '2019-20'::text) AND (playoff = false))
                                                  Buffers: shared hit=1906 read=336
                                            ->  Sort  (cost=1029.86..1029.95 rows=37 width=60) (actual time=0.483..0.493 rows=30 loops=2)
                                                  Sort Key: hg.home_team_id
                                                  Sort Method: quicksort  Memory: 27kB
                                                  Worker 0:  Sort Method: quicksort  Memory: 27kB
                                                  Buffers: shared hit=35 read=6
                                                  ->  Subquery Scan on hg  (cost=1028.06..1028.89 rows=37 width=60) (actual time=0.454..0.464 rows=30 loops=2)
                                                        Buffers: shared hit=35 read=6
                                                        ->  HashAggregate  (cost=1028.06..1028.52 rows=37 width=60) (actual time=0.452..0.460 rows=30 loops=2)
                                                              Group Key: games.home_team_id
                                                              Buffers: shared hit=35 read=6
                                                              ->  Bitmap Heap Scan on games  (cost=24.94..1013.50 rows=832 width=12) (actual time=0.113..0.282 rows=847 loops=2)
                                                                    Recheck Cond: ((season)::text = '2019-20'::text)
                                                                    Filter: (NOT playoff)
                                                                    Heap Blocks: exact=14
                                                                    Buffers: shared hit=35 read=6
                                                                    ->  Bitmap Index Scan on IDX__GAMES_2  (cost=0.00..24.73 rows=832 width=0) (actual time=0.098..0.099 rows=847 loops=2)
                                                                          Index Cond: (((season)::text = '2019-20'::text) AND (playoff = false))
                                                                          Buffers: shared hit=7 read=6
                                      ->  Sort  (cost=1029.86..1029.95 rows=37 width=32) (actual time=0.369..0.373 rows=30 loops=2)
                                            Sort Key: ag.away_team_id
                                            Sort Method: quicksort  Memory: 27kB
                                            Worker 0:  Sort Method: quicksort  Memory: 27kB
                                            Buffers: shared hit=40
                                            ->  Subquery Scan on ag  (cost=1028.06..1028.89 rows=37 width=32) (actual time=0.350..0.355 rows=30 loops=2)
                                                  Buffers: shared hit=40
                                                  ->  HashAggregate  (cost=1028.06..1028.52 rows=37 width=32) (actual time=0.349..0.353 rows=30 loops=2)
                                                        Group Key: games_1.away_team_id
                                                        Buffers: shared hit=40
                                                        ->  Bitmap Heap Scan on games games_1  (cost=24.94..1013.50 rows=832 width=12) (actual time=0.068..0.197 rows=847 loops=2)
                                                              Recheck Cond: ((season)::text = '2019-20'::text)
                                                              Filter: (NOT playoff)
                                                              Heap Blocks: exact=14
                                                              Buffers: shared hit=40
                                                              ->  Bitmap Index Scan on IDX__GAMES_2  (cost=0.00..24.73 rows=832 width=0) (actual time=0.062..0.062 rows=847 loops=2)
                                                                    Index Cond: (((season)::text = '2019-20'::text) AND (playoff = false))
                                                                    Buffers: shared hit=12
                                ->  Hash  (cost=13.20..13.20 rows=320 width=52) (actual time=0.039..0.040 rows=37 loops=2)
                                      Buckets: 1024  Batches: 1  Memory Usage: 11kB
                                      Buffers: shared hit=4
                                      ->  Seq Scan on teams t  (cost=0.00..13.20 rows=320 width=52) (actual time=0.024..0.031 rows=37 loops=2)
                                            Buffers: shared hit=4
Planning Time: 1.586 ms
Execution Time: 51.999 ms

0 个答案:

没有答案
相关问题