Đưa ra bảng:
Column | Type
id | integer
latitude | numeric(9,6)
longitude | numeric(9,6)
speed | integer
equipment_id | integer
created_at | timestamp without time zone
Indexes:
"geoposition_records_pkey" PRIMARY KEY, btree (id)
Bảng này có 20 triệu bản ghi , tương đối không phải là một con số lớn. Nhưng nó làm cho quét liên tiếp chậm.
Làm thế nào tôi có thể nhận được bản ghi cuối cùng ( max(created_at)
) của mỗi equipment_id
?
Tôi đã thử cả hai truy vấn sau đây, với một số biến thể mà tôi đã đọc qua nhiều câu trả lời của chủ đề này:
select max(created_at),equipment_id from geoposition_records group by equipment_id;
select distinct on (equipment_id) equipment_id,created_at
from geoposition_records order by equipment_id, created_at desc;
Tôi cũng đã thử tạo các chỉ mục btree cho equipment_id,created_at
nhưng Postgres thấy rằng sử dụng seqscan nhanh hơn. Buộc enable_seqscan = off
là không sử dụng được vì đọc chỉ số cũng chậm như quét seq, có thể tồi tệ hơn.
Truy vấn phải chạy định kỳ luôn luôn trả về lần cuối.
Sử dụng Postgres 9.3.
Giải thích / phân tích (với 1,7 triệu hồ sơ):
set enable_seqscan=true;
explain analyze select max(created_at),equipment_id from geoposition_records group by equipment_id;
"HashAggregate (cost=47803.77..47804.34 rows=57 width=12) (actual time=1935.536..1935.556 rows=58 loops=1)"
" -> Seq Scan on geoposition_records (cost=0.00..39544.51 rows=1651851 width=12) (actual time=0.029..494.296 rows=1651851 loops=1)"
"Total runtime: 1935.632 ms"
set enable_seqscan=false;
explain analyze select max(created_at),equipment_id from geoposition_records group by equipment_id;
"GroupAggregate (cost=0.00..2995933.57 rows=57 width=12) (actual time=222.034..11305.073 rows=58 loops=1)"
" -> Index Scan using geoposition_records_equipment_id_created_at_idx on geoposition_records (cost=0.00..2987673.75 rows=1651851 width=12) (actual time=0.062..10248.703 rows=1651851 loops=1)"
"Total runtime: 11305.161 ms"
NULL
giá trị nào trongequipment_id
tỷ lệ phần trăm dự kiến dưới 0,1%