Tôi có bảng sau với khoảng 175k hồ sơ:
Column | Type | Modifiers
----------------+-----------------------------+-------------------------------------
id | uuid | not null default uuid_generate_v4()
competition_id | uuid | not null
user_id | uuid | not null
first_name | character varying(255) | not null
last_name | character varying(255) | not null
image | character varying(255) |
country | character varying(255) |
slug | character varying(255) | not null
total_votes | integer | not null default 0
created_at | timestamp without time zone |
updated_at | timestamp without time zone |
featured_until | timestamp without time zone |
image_src | character varying(255) |
hidden | boolean | not null default false
photos_count | integer | not null default 0
photo_id | uuid |
Indexes:
"entries_pkey" PRIMARY KEY, btree (id)
"index_entries_on_competition_id" btree (competition_id)
"index_entries_on_featured_until" btree (featured_until)
"index_entries_on_hidden" btree (hidden)
"index_entries_on_photo_id" btree (photo_id)
"index_entries_on_slug" btree (slug)
"index_entries_on_total_votes" btree (total_votes)
"index_entries_on_user_id" btree (user_id)
và tôi đang thực hiện truy vấn sau để có thứ hạng của mục nhập và sên của mục tiếp theo và mục trước:
WITH entry_with_global_rank AS (
SELECT id
, rank() OVER w AS global_rank
, LAG(slug) OVER w AS previous_slug
, LEAD(slug) OVER w AS next_slug
FROM entries
WHERE competition_id = 'bdd94eee-25a4-481f-b7b5-37aaed953c6b'
WINDOW w AS (PARTITION BY competition_id ORDER BY total_votes DESC)
)
SELECT *
FROM entry_with_global_rank
WHERE id = 'f2df68b7-d720-459d-8c4d-d11e28e0f0c0'
LIMIT 1;
Đây là kết quả từ EXPLAIN
:
QUERY PLAN
-----------------------------------------------------------------------------------------------
Limit (cost=516228.88..516233.37 rows=1 width=88)
CTE entry_with_global_rank
-> WindowAgg (cost=510596.59..516228.88 rows=250324 width=52)
-> Sort (cost=510596.59..511222.40 rows=250324 width=52)
Sort Key: entries.total_votes
-> Seq Scan on entries (cost=0.00..488150.74 rows=250324 width=52)
Filter: (competition_id = 'bdd94eee-25a4-481f-b7b5-37aaed953c6b'::uuid)
-> CTE Scan on entry_with_global_rank (cost=0.00..5632.29 rows=1252 width=88)
Filter: (id = 'f2df68b7-d720-459d-8c4d-d11e28e0f0c0'::uuid)
(9 rows)
Truy vấn này mất ~ 1400ms; Có cách nào để tăng tốc độ này không?
Biên tập:
Đây là kết quả từ EXPLAIN ANALYZE
:
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=516228.88..516233.37 rows=1 width=88) (actual time=1232.824..1232.824 rows=1 loops=1)
CTE entry_with_global_rank
-> WindowAgg (cost=510596.59..516228.88 rows=250324 width=52) (actual time=1202.101..1226.846 rows=8727 loops=1)
-> Sort (cost=510596.59..511222.40 rows=250324 width=52) (actual time=1202.069..1213.992 rows=8728 loops=1)
Sort Key: entries.total_votes
Sort Method: quicksort Memory: 8128kB
-> Seq Scan on entries (cost=0.00..488150.74 rows=250324 width=52) (actual time=89.970..1174.083 rows=50335 loops=1)
Filter: (competition_id = 'bdd94eee-25a4-481f-b7b5-37aaed953c6b'::uuid)
Rows Removed by Filter: 125477
-> CTE Scan on entry_with_global_rank (cost=0.00..5632.29 rows=1252 width=88) (actual time=1232.822..1232.822 rows=1 loops=1)
Filter: (id = 'f2df68b7-d720-459d-8c4d-d11e28e0f0c0'::uuid)
Rows Removed by Filter: 8726
Total runtime: 1234.424 ms
(13 rows)
Chỉnh sửa 2:
Tôi đã chạy VACUUM ANALYZE
trên cơ sở dữ liệu và bây giờ thời gian truy vấn đã được cải thiện, mặc dù tôi chắc chắn phải có một số cách để cải thiện hiệu suất:
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=475372.26..475376.76 rows=1 width=88) (actual time=138.388..138.388 rows=1 loops=1)
CTE entry_with_global_rank
-> WindowAgg (cost=470662.23..475372.26 rows=209335 width=35) (actual time=125.489..132.214 rows=4178 loops=1)
-> Sort (cost=470662.23..471185.56 rows=209335 width=35) (actual time=125.462..126.724 rows=4179 loops=1)
Sort Key: entries.total_votes
Sort Method: quicksort Memory: 5510kB
-> Bitmap Heap Scan on entries (cost=71390.90..452161.77 rows=209335 width=35) (actual time=29.381..87.130 rows=50390 loops=1)
Recheck Cond: (competition_id = 'bdd94eee-25a4-481f-b7b5-37aaed953c6b'::uuid)
-> Bitmap Index Scan on index_entries_on_competition_id (cost=0.00..71338.56 rows=209335 width=0) (actual time=23.593..23.593 rows=51257 loops=1)
Index Cond: (competition_id = 'bdd94eee-25a4-481f-b7b5-37aaed953c6b'::uuid)
-> CTE Scan on entry_with_global_rank (cost=0.00..4710.04 rows=1047 width=88) (actual time=138.387..138.387 rows=1 loops=1)
Filter: (id = '9470ec4f-fed1-4f95-bbed-1e3dbba5f53b'::uuid)
Rows Removed by Filter: 4177
Total runtime: 138.588 ms
(14 rows)
Chỉnh sửa 3:
Theo yêu cầu, kế hoạch truy vấn cuối cùng với chỉ số bao phủ tại chỗ, ngay sau VACUUM ANALYZE
:
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.42..6771.99 rows=1 width=88) (actual time=46.765..46.765 rows=1 loops=1)
-> Subquery Scan on entry_with_global_rank (cost=0.42..6771.99 rows=1 width=88) (actual time=46.763..46.763 rows=1 loops=1)
Filter: (entry_with_global_rank.id = 'f2df68b7-d720-459d-8c4d-d11e28e0f0c0'::uuid)
Rows Removed by Filter: 9128
-> WindowAgg (cost=0.42..5635.06 rows=90955 width=35) (actual time=0.090..40.002 rows=9129 loops=1)
-> Index Only Scan using entries_extra_special_idx on entries (cost=0.42..3815.96 rows=90955 width=35) (actual time=0.071..10.973 rows=9130 loops=1)
Index Cond: (competition_id = 'bdd94eee-25a4-481f-b7b5-37aaed953c6b'::uuid)
Heap Fetches: 166
Total runtime: 46.867 ms
(9 rows)
competition_id = 'bdd94eee-25a4-481f-b7b5-37aaed953c6b'
. Sử dụng GIẢI THÍCH ANALYZE để có được số lượng thực tế. Tính chọn lọc của ID cụ thể này là chìa khóa ở đây.
PARTITION BY competition_id
chỉ có một giá trị (do WHERE
điều khoản).