รับตาราง:
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)
ตารางมี 20 ล้านบันทึกที่ไม่ได้พูดค่อนข้างมาก แต่มันทำให้การสแกนตามลำดับช้าลง
ฉันจะได้รับบันทึกสุดท้ายmax(created_at)
ของแต่ละรายการได้equipment_id
อย่างไร
ฉันได้ลองค้นหาทั้งสองข้อต่อไปนี้โดยมีหลายรุ่นที่ฉันได้อ่านจากคำตอบของหัวข้อนี้:
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;
ฉันได้ลองสร้างดัชนี btree ด้วยequipment_id,created_at
แต่ Postgres พบว่าการใช้ seqscan นั้นเร็วกว่า การบังคับenable_seqscan = off
ไม่ได้ใช้อย่างใดอย่างหนึ่งเนื่องจากการอ่านดัชนีช้าเท่ากับการสแกน seq ซึ่งอาจแย่กว่านั้น
แบบสอบถามต้องเรียกใช้การส่งคืนเป็นระยะสุดท้ายเสมอ
ใช้ Postgres 9.3
อธิบาย / วิเคราะห์ (มี 1.7 ล้านบันทึก):
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
ค่าใด ๆในequipment_id
เปอร์เซ็นต์ที่คาดว่าจะต่ำกว่า 0.1%