【发布时间】:2022-01-27 21:16:07
【问题描述】:
我使用的是 PostgreSQL 14.1。我的查询如下所示:
SELECT stats_game.id AS stats_game_id,
stats_fighters.left_fighter AS stats_fighters_left_fighter,
stats_fighters.right_fighter AS stats_fighters_right_fighter,
stats_timestamp.ts AS stats_timestamp_ts,
stats_timestamp.time_of_day AS stats_timestamp_time_of_day,
stats_coefs.wl AS stats_coefs_wl,
stats_coefs.wr AS stats_coefs_wr,
stats_coefs.wlr AS stats_coefs_wlr,
stats_coefs.wrr AS stats_coefs_wrr,
stats_coefs.f AS stats_coefs_f,
stats_coefs.b AS stats_coefs_b,
stats_coefs.r AS stats_coefs_r,
stats_coefs.flaw AS stats_coefs_flaw,
stats_rounds.one AS stats_rounds_one,
stats_rounds.two AS stats_rounds_two,
stats_rounds.three AS stats_rounds_three,
stats_rounds.four AS stats_rounds_four,
stats_rounds.five AS stats_rounds_five,
stats_rounds.six AS stats_rounds_six,
stats_rounds.seven AS stats_rounds_seven,
stats_rounds.eight AS stats_rounds_eight,
stats_rounds.nine AS stats_rounds_nine,
stats_roundsview.one_view AS stats_roundsview_one_view,
stats_roundsview.two_view AS stats_roundsview_two_view,
stats_roundsview.three_view AS stats_roundsview_three_view,
stats_roundsview.four_view AS stats_roundsview_four_view,
stats_roundsview.five_view AS stats_roundsview_five_view,
stats_roundsview.six_view AS stats_roundsview_six_view,
stats_roundsview.seven_view AS stats_roundsview_seven_view,
stats_roundsview.eight_view AS stats_roundsview_eight_view,
stats_roundsview.nine_view AS stats_roundsview_nine_view,
stats_roundsviewfinish.one_view_f AS stats_roundsviewfinish_one_view_f,
stats_roundsviewfinish.two_view_f AS stats_roundsviewfinish_two_view_f,
stats_roundsviewfinish.three_view_f AS stats_roundsviewfinish_three_view_f,
stats_roundsviewfinish.four_view_f AS stats_roundsviewfinish_four_view_f,
stats_roundsviewfinish.five_view_f AS stats_roundsviewfinish_five_view_f,
stats_roundsviewfinish.six_view_f AS stats_roundsviewfinish_six_view_f,
stats_roundsviewfinish.seven_view_f AS stats_roundsviewfinish_seven_view_f,
stats_roundsviewfinish.eight_view_f AS stats_roundsviewfinish_eight_view_f,
stats_roundsviewfinish.nine_view_f AS stats_roundsviewfinish_nine_view_f,
stats_finishes.one_f AS stats_finishes_one_f,
stats_finishes.two_f AS stats_finishes_two_f,
stats_finishes.three_f AS stats_finishes_three_f,
stats_finishes.four_f AS stats_finishes_four_f,
stats_finishes.five_f AS stats_finishes_five_f,
stats_finishes.six_f AS stats_finishes_six_f,
stats_finishes.seven_f AS stats_finishes_seven_f,
stats_finishes.eight_f AS stats_finishes_eight_f,
stats_finishes.nine_f AS stats_finishes_nine_f,
stats_score.first_score AS stats_score_first_score,
stats_score.second_score AS stats_score_second_score,
stats_score.is_rusk AS stats_score_is_rusk,
stats_roundstime.first_t AS stats_roundstime_first_t,
stats_roundstime.second_t AS stats_roundstime_second_t,
stats_roundstime.third_t AS stats_roundstime_third_t,
stats_roundstime.fourth_t AS stats_roundstime_fourth_t,
stats_roundstime.fifth_t AS stats_roundstime_fifth_t,
stats_roundstime.sixth_t AS stats_roundstime_sixth_t,
stats_roundstime.seventh_t AS stats_roundstime_seventh_t,
stats_roundstime.eighth_t AS stats_roundstime_eighth_t,
stats_roundstime.ninth_t AS stats_roundstime_ninth_t,
stats_roundtime.min_time AS stats_roundtime_min_time,
stats_roundtime.mean_time AS stats_roundtime_mean_time,
stats_roundtime.max_time AS stats_roundtime_max_time,
stats_timecoef.min_coef_less AS stats_timecoef_min_coef_less,
stats_timecoef.mean_coef_less AS stats_timecoef_mean_coef_less,
stats_timecoef.max_coef_less AS stats_timecoef_max_coef_less,
stats_timecoef.min_coef_more AS stats_timecoef_min_coef_more,
stats_timecoef.mean_coef_more AS stats_timecoef_mean_coef_more,
stats_timecoef.max_coef_more AS stats_timecoef_max_coef_more,
stats_totals.five_total_more AS stats_totals_five_total_more,
stats_totals.five_total_less AS stats_totals_five_total_less,
stats_totals.six_total_more AS stats_totals_six_total_more,
stats_totals.six_total_less AS stats_totals_six_total_less,
stats_totals.seven_total_more AS stats_totals_seven_total_more,
stats_totals.seven_total_less AS stats_totals_seven_total_less,
stats_totals.eight_total_more AS stats_totals_eight_total_more,
stats_totals.eight_total_less AS stats_totals_eight_total_less
FROM stats_game
JOIN stats_fighters ON stats_game.id = stats_fighters.game_id
JOIN stats_timestamp ON stats_game.id = stats_timestamp.game_id
JOIN stats_coefs ON stats_game.id = stats_coefs.game_id
JOIN stats_rounds ON stats_game.id = stats_rounds.game_id
JOIN stats_roundsview ON stats_game.id = stats_roundsview.game_id
JOIN stats_roundsviewfinish ON stats_game.id = stats_roundsviewfinish.game_id
JOIN stats_finishes ON stats_game.id = stats_finishes.game_id
JOIN stats_score ON stats_game.id = stats_score.game_id
JOIN stats_roundstime ON stats_game.id = stats_roundstime.game_id
JOIN stats_roundtime ON stats_game.id = stats_roundtime.game_id
JOIN stats_timecoef ON stats_game.id = stats_timecoef.game_id
JOIN stats_totals ON stats_game.id = stats_totals.game_id
ORDER BY stats_game.id DESC LIMIT 200
这是解释结果:
Limit (cost=3.71..141.01 rows=200 width=413) (actual time=0.263..4.807 rows=200 loops=1)
Buffers: shared hit=608
-> Merge Join (cost=3.71..7140.27 rows=10395 width=413) (actual time=0.262..4.754 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_score.game_id)
Buffers: shared hit=608
-> Merge Join (cost=3.42..7228.43 rows=11490 width=448) (actual time=0.245..4.364 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_totals.game_id)
Buffers: shared hit=572
-> Merge Join (cost=3.14..7202.47 rows=12700 width=380) (actual time=0.230..3.939 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_timecoef.game_id)
Buffers: shared hit=500
-> Merge Join (cost=2.85..6409.88 rows=12700 width=328) (actual time=0.215..3.520 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_roundtime.game_id)
Buffers: shared hit=421
-> Merge Join (cost=2.57..5665.95 rows=12700 width=300) (actual time=0.199..3.109 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_roundstime.game_id)
Buffers: shared hit=347
-> Merge Join (cost=2.28..4906.03 rows=12700 width=260) (actual time=0.181..2.714 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_roundsview.game_id)
Buffers: shared hit=318
-> Merge Join (cost=2.00..4680.43 rows=14037 width=233) (actual time=0.154..2.256 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_roundsviewfinish.game_id)
Buffers: shared hit=251
-> Merge Join (cost=1.71..4384.11 rows=15515 width=190) (actual time=0.130..1.861 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_finishes.game_id)
Buffers: shared hit=222
-> Merge Join (cost=1.43..3620.00 rows=15515 width=168) (actual time=0.116..1.447 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_rounds.game_id)
Buffers: shared hit=152
-> Merge Join (cost=1.14..2824.88 rows=15515 width=128) (actual time=0.097..1.101 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_coefs.game_id)
Buffers: shared hit=123
-> Merge Join (cost=0.86..1967.77 rows=15515 width=60) (actual time=0.069..0.747 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_timestamp.game_id)
Buffers: shared hit=74
-> Merge Join (cost=0.57..1203.66 rows=15515 width=40) (actual time=0.043..0.434 rows=200 loops=1)
Merge Cond: (stats_game.id = stats_fighters.game_id)
Buffers: shared hit=38
-> Index Only Scan Backward using stats_game_pkey on stats_game (cost=0.29..413.33 rows=15536 width=4) (actual time=0.025..0.090 rows=200 loops=1)
Heap Fetches: 0
Buffers: shared hit=4
-> Index Scan Backward using stats_fighters_game_id_5873ae20 on stats_fighters (cost=0.29..557.56 rows=15515 width=36) (actual time=0.013..0.148 rows=200 loops=1)
Buffers: shared hit=34
-> Index Scan Backward using stats_timestamp_game_id_7cba64ec on stats_timestamp (cost=0.29..531.34 rows=15536 width=20) (actual time=0.023..0.133 rows=200 loops=1)
Buffers: shared hit=36
-> Index Scan Backward using stats_coefs_game_id_4945e660 on stats_coefs (cost=0.29..624.33 rows=15536 width=68) (actual time=0.026..0.144 rows=200 loops=1)
Buffers: shared hit=49
-> Index Scan Backward using stats_rounds_game_id_3021918d on stats_rounds (cost=0.29..562.33 rows=15536 width=40) (actual time=0.017..0.125 rows=200 loops=1)
Buffers: shared hit=29
-> Index Scan Backward using stats_finishes_game_id_2cae9f9f on stats_finishes (cost=0.29..531.34 rows=15536 width=22) (actual time=0.011..0.147 rows=200 loops=1)
Buffers: shared hit=70
-> Index Scan Backward using stats_roundsviewfinish_game_id_4613fecf on stats_roundsviewfinish (cost=0.29..523.43 rows=14056 width=43) (actual time=0.020..0.123 rows=200 loops=1)
Buffers: shared hit=29
-> Index Scan Backward using stats_roundsview_game_id_5e0e170b on stats_roundsview (cost=0.29..499.15 rows=14056 width=27) (actual time=0.023..0.154 rows=200 loops=1)
Buffers: shared hit=67
-> Index Scan Backward using stats_roundstime_game_id_503d284c on stats_roundstime (cost=0.29..562.34 rows=15536 width=40) (actual time=0.015..0.125 rows=200 loops=1)
Buffers: shared hit=29
-> Index Scan Backward using stats_roundtime_game_id_7bb54c53 on stats_roundtime (cost=0.29..546.34 rows=15536 width=28) (actual time=0.012..0.140 rows=200 loops=1)
Buffers: shared hit=74
-> Index Scan Backward using stats_timecoef_game_id_cee96f92 on stats_timecoef (cost=0.29..595.00 rows=15536 width=52) (actual time=0.010..0.132 rows=200 loops=1)
Buffers: shared hit=79
-> Index Scan Backward using stats_totals_game_id_dc1ed7ed on stats_totals (cost=0.29..566.14 rows=14056 width=68) (actual time=0.011..0.127 rows=200 loops=1)
Buffers: shared hit=72
-> Index Scan Backward using stats_score_game_id_a4e3e3f5 on stats_score (cost=0.29..468.14 rows=14056 width=13) (actual time=0.012..0.117 rows=200 loops=1)
Buffers: shared hit=36
Planning:
Buffers: shared hit=786
Planning Time: 135.963 ms
Execution Time: 5.172 ms
这是我的索引:
schemaname | tablename | indexname | tablespace | indexdef
------------+------------------------+-----------------------------------------+------------+-------------------------------------------------------------------------------------------------------------
public | stats_coefs | stats_coefs_pkey | | CREATE UNIQUE INDEX stats_coefs_pkey ON public.stats_coefs USING btree (id)
public | stats_fighters | stats_fighters_pkey | | CREATE UNIQUE INDEX stats_fighters_pkey ON public.stats_fighters USING btree (id)
public | stats_finishes | stats_finishes_pkey | | CREATE UNIQUE INDEX stats_finishes_pkey ON public.stats_finishes USING btree (id)
public | stats_game | stats_game_pkey | | CREATE UNIQUE INDEX stats_game_pkey ON public.stats_game USING btree (id)
public | stats_rounds | stats_rounds_pkey | | CREATE UNIQUE INDEX stats_rounds_pkey ON public.stats_rounds USING btree (id)
public | stats_roundstime | stats_roundstime_pkey | | CREATE UNIQUE INDEX stats_roundstime_pkey ON public.stats_roundstime USING btree (id)
public | stats_roundsview | stats_roundsview_pkey | | CREATE UNIQUE INDEX stats_roundsview_pkey ON public.stats_roundsview USING btree (id)
public | stats_roundsviewfinish | stats_roundsviewfinish_pkey | | CREATE UNIQUE INDEX stats_roundsviewfinish_pkey ON public.stats_roundsviewfinish USING btree (id)
public | stats_roundtime | stats_roundtime_pkey | | CREATE UNIQUE INDEX stats_roundtime_pkey ON public.stats_roundtime USING btree (id)
public | stats_score | stats_score_pkey | | CREATE UNIQUE INDEX stats_score_pkey ON public.stats_score USING btree (id)
public | stats_timecoef | stats_timecoef_pkey | | CREATE UNIQUE INDEX stats_timecoef_pkey ON public.stats_timecoef USING btree (id)
public | stats_timestamp | stats_timestamp_pkey | | CREATE UNIQUE INDEX stats_timestamp_pkey ON public.stats_timestamp USING btree (id)
public | stats_totals | stats_totals_pkey | | CREATE UNIQUE INDEX stats_totals_pkey ON public.stats_totals USING btree (id)
public | stats_coefs | stats_coefs_game_id_4945e660 | | CREATE INDEX stats_coefs_game_id_4945e660 ON public.stats_coefs USING btree (game_id)
public | stats_fighters | stats_fighters_game_id_5873ae20 | | CREATE INDEX stats_fighters_game_id_5873ae20 ON public.stats_fighters USING btree (game_id)
public | stats_finishes | stats_finishes_game_id_2cae9f9f | | CREATE INDEX stats_finishes_game_id_2cae9f9f ON public.stats_finishes USING btree (game_id)
public | stats_rounds | stats_rounds_game_id_3021918d | | CREATE INDEX stats_rounds_game_id_3021918d ON public.stats_rounds USING btree (game_id)
public | stats_roundstime | stats_roundstime_game_id_503d284c | | CREATE INDEX stats_roundstime_game_id_503d284c ON public.stats_roundstime USING btree (game_id)
public | stats_roundsview | stats_roundsview_game_id_5e0e170b | | CREATE INDEX stats_roundsview_game_id_5e0e170b ON public.stats_roundsview USING btree (game_id)
public | stats_roundsviewfinish | stats_roundsviewfinish_game_id_4613fecf | | CREATE INDEX stats_roundsviewfinish_game_id_4613fecf ON public.stats_roundsviewfinish USING btree (game_id)
public | stats_roundtime | stats_roundtime_game_id_7bb54c53 | | CREATE INDEX stats_roundtime_game_id_7bb54c53 ON public.stats_roundtime USING btree (game_id)
public | stats_score | stats_score_game_id_a4e3e3f5 | | CREATE INDEX stats_score_game_id_a4e3e3f5 ON public.stats_score USING btree (game_id)
public | stats_timecoef | stats_timecoef_game_id_cee96f92 | | CREATE INDEX stats_timecoef_game_id_cee96f92 ON public.stats_timecoef USING btree (game_id)
public | stats_timestamp | stats_timestamp_game_id_7cba64ec | | CREATE INDEX stats_timestamp_game_id_7cba64ec ON public.stats_timestamp USING btree (game_id)
public | stats_totals | stats_totals_game_id_dc1ed7ed | | CREATE INDEX stats_totals_game_id_dc1ed7ed ON public.stats_totals USING btree (game_id)
我是优化查询方面的菜鸟,并不真正了解如何阅读此 EXPLAIN 语句。
有什么办法可以提高这个查询的速度吗?它通常需要大约 500 毫秒,这是巨大的。我想知道是否可以使用一些简单的优化,但也想知道是否有一种方法可以创建物化视图和触发器,还是不值得?
【问题讨论】:
-
请显示
EXPLAIN (ANALYZE, BUFFERS),而不仅仅是解释。这样我们就可以看到它在每个节点上实际找到了多少行,以及它预计会找到多少行,以及实际花费了多长时间。 -
@jjanes 不知道这个。完成。
标签: sql postgresql query-optimization